>  기사  >  백엔드 개발  >  고급 Python 학습을 위한 소켓에 대한 자세한 소개

고급 Python 학습을 위한 소켓에 대한 자세한 소개

高洛峰
高洛峰원래의
2017-03-19 14:57:521258검색

소켓(Socket)의 원래 영어 의미는 "구멍" 또는 "소켓"입니다. BSD UNIX의 프로세스 통신 메커니즘으로 일반적으로 "소켓"이라고도 하며 IP 주소와 포트를 설명하는 데 사용됩니다. 통신 체인의 핸들이며 서로 다른 가상 머신 또는 서로 다른 컴퓨터 간의 통신을 구현하는 데 사용할 수 있습니다. .

네트워크상의 두 프로그램은 양방향 통신 연결을 통해 데이터를 교환합니다. 이 연결의 한쪽 끝을 소켓이라고 합니다.

네트워크 통신 연결을 설정하려면 최소한 한 쌍의 포트 번호(소켓)가 필요합니다. 소켓의 핵심은 프로그래밍인터페이스(API)입니다. TCP/IP를 캡슐화하려면 TCP/IP도 이를 제공해야 합니다. 프로그래머용 네트워크 개발에 사용되는 인터페이스는 소켓 프로그래밍 인터페이스이고, HTTP는 데이터를 캡슐화하거나 표시하는 특정 형식을 제공하는 자동차입니다. 소켓은 네트워크 통신 기능을 제공하는 엔진입니다.

파이썬의 소켓에 대해 이야기해보겠습니다.

1.socket 모듈

은 Socket.socket()함수를 사용하여 소켓을 생성합니다. 구문은 다음과 같습니다.

socket.socket(socket_family,socket_type,protocol=0)

socket_family는 다음 매개변수일 수 있습니다.

소켓.AF_INET IPv4(기본값)

소켓.AF_INET6 IPv6

소켓.AF_UNIX는 단일 Unix 시스템의 프로세스 간 통신에만 사용할 수 있습니다.

socket_type은 다음 매개변수일 수 있습니다.

소켓.SOCK_STREAM 스트리밍 소켓, TCP용(기본값)

소켓.SOCK_DGRAM 데이터그램 소켓, UDP용

소켓.SOCK_RAW 원시 소켓, 일반 소켓은 ICMP를 처리할 수 없습니다. , IGMP 및 기타 네트워크 메시지는 가능하지만 SOCK_RAW는 또한 특수 IPv4 메시지도 처리할 수 있습니다. 또한 원시 소켓을 사용하면 IP_HDRINCL 소켓 옵션을 통해 IP 헤더를 구성할 수 있습니다.

Socket.SOCK_RDM은 신뢰할 수 있는 UDP 형식으로 데이터그램 전달을 보장하지만 순서를 보장하지는 않습니다. SOCK_RAM은 원래 프로토콜에 대한 낮은 수준의 액세스를 제공하는 데 사용되며 ICMP 메시지 전송과 같은 특정 특수 작업을 수행해야 할 때 사용됩니다. SOCK_RAM은 일반적으로 고급 사용자나 관리자가 실행하는 프로그램으로 제한됩니다.

socket.SOCK_SEQPACKET 안정적인 연속 패킷 서비스

프로토콜 매개변수:

0(기본값) 특정 주소 계열과 관련된 프로토콜이 0인 경우 시스템은 A를 수행합니다. 주소 형식과 소켓 유형에 따라 적합한 프로토콜이 자동으로 선택됩니다.

2.소켓객체내장 방식

서버 측 소켓 기능

s.bind()  주소(IP 주소, 포트)를 소켓에 바인딩합니다. 매개변수는 튜플 형식이어야 합니다. 예: s.bind(('127.0.0.1',8009))

s.listen(5) 듣기 시작, 5는 보류 중인 최대 연결 수

s.accept() 수동적으로 클라이언트 연결 수락, 연결 차단 및 대기

클라이언트 소켓 Word 기능

s.connect() 서버에 연결하려면 매개변수가 튜플 형식이어야 합니다. 예: s.connect(('127,0.0.1',8009))

공용 소켓 기능

s.recv(1024) TCP 데이터 수신, 1024는 데이터 수신 1회 크기

s.send(bytes) TCP 데이터 전송, python3 데이터 전송 형식 바이트 형식이어야 합니다.

s.sendall() 데이터 완전 전송, 내부 루프 호출 send

s.close() 소켓 닫기

예 1 .간단한 소켓 프로그램 구현

서버측

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import socket
import time
IP_PORT = ('127.0.0.1',8009)
BUF_SIZE = 1024
 
tcp_server = socket.socket()
tcp_server.bind(IP_PORT)
tcp_server.listen(5)
 
while True:
    print("waiting for connection...")
    conn,addr = tcp_server.accept()
    print("...connected from:",addr)
    while True:
        data = tcp_server.recv(BUF_SIZE)
        if not data:break
        tcp_server.send('[%s] %s'%(time.ctime(),data))
 
tcp_server.close()

위 코드 설명:

1~4줄

첫 번째 줄은 Unix 시작 정보 라인을 가져옵니다.

라인 5~10

IP_PORT는 전역 변수 에 대한 IP 주소와 포트를 선언합니다. ) 함수는 이 주소에 바인딩됩니다. 위에서 버퍼 크기를 1K로 설정합니다. Listen() 함수는 동시에 들어올 수 있는 최대 연결 수를 나타냅니다.

11~到最后一行

在进入服务器的循环后,被动等待连接的到来。当有连接时,进入对话循环,等待客户端发送数据。如果消息为空,表示客户端已经退出,就跳出循环等待下一个连接到来。得到客户端消息后,在消息前面加一个时间戳然后返回。最后一行不会执行,因为循环不会退出所以服务端也不会执行close()。只是提醒不要忘记调用close()函数。

client端

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import socket
 
HOST = '127.0.0.1'
PORT = 8009
BUF_SIZE = 1024
ADDR = (HOST,PORT)
 
client = socket.socket()
client.connect(ADDR)
 
while True:
    data = input(">>> ")
    if not data:break
    client.send(bytes(data,encoding='utf-8'))
    recv_data = client.recv(BUF_SIZE)
    if not recv_data:break
    print(recv_data.decode())
     
client.close()

5~11行

HOST和PORT变量表示服务器的IP地址与端口号。由于演示是在同一台服务器所以IP地址都是127.0.0.1,如果运行在其他服务器上要做相应的修改。端口号要与服务器端完全相同否则无法通信。缓冲区大小还是1K。

客户端套接字在10行创建然后就去连接服务器端

13~21行

客户端也无限循环,客户端的循环在以下两个条件的任意一个发生后就退出:1.用户输入为空的情况或者服务器端响应的消息为空。否则客户端会把用户输入的字符串发送给服务器进行处理,然后接收显示服务器返回来的带有时间戳的字符串。

运行客户端程序与服务端程序

以下是客户端的输入与输出

[root@pythontab]# python client.py 
>>> hello python
[Thu Sep 15 22:29:12 2016] b'hello python'

以下是服务端输出

[root@pythontab]# python server.py 
waiting for connection...
...connected from: ('127.0.0.1', 55378)

3.socketserver模块

socketserver是标准库中的一个高级别的模块。用于简化实现网络客户端与服务器所需要的大量样板代码。模块中已经实现了一些可以使用的类。

实例1:使用socketserver实现与上面socket()实例一样的功能

服务端程序代码

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import socketserver
import time
 
HOST = '127.0.0.1'
PORT = 8009
ADDR = (HOST,PORT)
BUF_SIZE = 1024
 
class Myserver(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            print("...connected from:",self.client_address)
            data = self.request.recv(BUF_SIZE)
            if not data:break
            self.request.send(bytes("%s %s"%(time.ctime(),data)))
 
server = socketserver.ThreadingTCPServer(ADDR,Myserver)
print("waiting for connection...")
server.serve_forever()

11~17行

主要的工作在这里。从socketserver的BaseRequestHandler类中派生出一个子类,并重写handle()函数。

在有客户端发进来的消息的时候,handle()函数就会被调用。

19~21行

代码的最后一部分用给定的IP地址和端口加上自定义处理请求的类(Myserver)。然后进入等待客户端请求与处理客户端请求的无限循环中。

客户端程序代码

import socket
HOST = '127.0.0.1'
PORT = 8009
ADDR = (HOST,PORT)
BUF_SIZE = 1024
 
client = socket.socket()
client.connect(ADDR)
 
while True:
    data = input(">>> ")
    if not data:continue
    client.send(bytes(data,encoding='utf-8'))
    recv_data = client.recv(BUF_SIZE)
    if not recv_data:break
    print(recv_data.decode())
 
client.close()

执行服务端和客户端代码  

下面是客户端输出

[root@pythontab]# python socketclient.py 
>>> hello python
Thu Sep 15 23:53:31 2016 b'hello python'
>>> hello pythontab
Thu Sep 15 23:53:49 2016 b'hello pythontab'

下面是服务端输出

[root@pythontab]# python socketserver.py 
waiting for connection...
...connected from: ('127.0.0.1', 55385)
...connected from: ('127.0.0.1', 55385)
...connected from: ('127.0.0.1', 55385)
...connected from: ('127.0.0.1', 55385)

위 내용은 고급 Python 학습을 위한 소켓에 대한 자세한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.