Socket(套接字),应用程序通常通过”套接字”向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。服务器端:socket()
建立套接字,绑定(bind)并监听(listen),用accept()等待客户端连接。将accept()写入死循环,每次连接一个客户端,开一个线程。一般情况下建立socket
连接后服务器与客户端建立了一个管道,当关闭socket
或关闭客户端的时候,会导致管道破裂信号。如果使用默认处理则会导致服务器程序退出。
0. socket函数
1 | socket.socket(family, type, protocol) |
参数:
- family: 套接字python家族支持
AF_UNIX
、AF_INET
、AF_NETLINK
和AF_INET
- type: 套接字类型可以根据是面向连接的还是非连接分为
SOCK_STREAM
或SOCK_DGRAM
,其中SOCK_STREAM
是tcp类型的,SOCK_DGRAM
是udp类型的 - protocol: 一般不填默认为0.
1. 简单的样例通信样例
1.1 TCP服务端
TCP是面向连接的,可靠的流协议。流就是不间断的数据结构
1 | # for python3.X |
由于Python2.x和Python3.x的区别,socket通信在3.x版本中需要适应encode()
和decode()
编解码,而python3.x最重要的新特性也是对文本和二进制数据做了更清晰的区分。文本用unicode
编码,为str类型,二进制数据则为bytes类型。encode
(编码),可以将str类型编码为bytes。decode
(译码),可以将bytes类型转换为str类型。
注意:如果不添加encode()和decode()就会报Socket TypeError: a bytes-like object is required, not 'str'
的错误,因此在发送的时候记得将数据encode()
,接收的时候将数据decode()
1.2 TCP客户端
1 | import socket |
1.3 UDP服务端
UDP是一种无连接的,不具有可靠性的数据报文协议
这个是插入时间戳的例子,同理这个还可以在tcp的socket实现,各位看官自己实现吧
1 | # for python3.X |
1.4 UDP客户端
1 | from socket import * |
综上所述,可以得到这样的结论: socket
通信,服务器端 要开启一个对应udp或者tcp的scoket
,在这个socket
里面指定通信的端口的地址;udp服务器的socket
这样起,udpScoket=socket(AF_INET, SOCK_DGRAM)
; 然后在udpSocket
里面调用bind()
方法绑定通信的地址addr=(host, port)
,也就是udpSocket.bind(addr)
;然后在开启一个循环通过recvfrom()
方法接收udp数据,data, addr = udpSocket.recvfrom(buffersize)
,发送出去的话就利用sendto()
方法,udpSocket.sendto(('[%s] %s' % (ctime(), data)).encode(), addr)
。tcp的socket
相对于udp的socket是一种可靠的传输,在起socket
的时候不同于udp的主要有两点,一是利用SOCK_STREAM
,二是tcp的通信需要在一段时间内监听通信端口是否有数据发来,这是tcp协议所特有的。客户端 服务器端开启了socket
服务之后,socket
客户端需要对应服务器开启一个对应的socket
客户端:tcp开udpClient=socket(AF_INET, SOCK_STREAM)
,然后让这个客户端的socket
连接到服务器的socket
;也就是tcpClient.connect(ADDR)' 这里ADDR=(host, port)
udpClient=socket(AF_INET, SOCK_DGRAM)这样客户端就和服务器连接起来了;客户端样用
recv()方法接收服务器的数据;用
send()方法将数据发送到服务器。udp客户同tcp的方法一样,跟对应模式的
socket`方法一直,端口对端口,地址对地址。
2、socketserver模块
socketserver
是标准库中的一个高级模块,用于网络客户端与服务器的实现,模块定义了一些类来处理诸如TCP、UDP、UNIX流和UNIX数据报之上的同步网络请求。;python3中,导入socketserver
模块, 使用import socketserver
. 在使用socketserver的时候必须说先定义一个继承BaseRequestHandler
的处理类。
socketserver
模块中包含的类:
BaseServer
包含服务器的核心功能与混合类(min-in)的钩子功能.这个类主用于派生,不要直接生成这个类的类对象,可以考虑使用;TCPServer/UDPServer
TCPServer
基本的网络同步tcp服务器/UDPServer
基本的网络同步udp服务器;ForkingMinIn
实现了核心的进程化功能,用于与服务器类进行混合(min-in),以提供一些异步特性.不要直接生成这个类的对象;ThreadingMinIn
实现了核心的线程化功能,用于与服务器类进行混合(min-in),以提供一些异步特性,不要直接生成这个类的对象;ForkingTCPServer/ForkingUDPServer
ForkingMinIn
与TCPServer
的组合/ForkingMinIn
与UDPServer
的组合;BaseRequestHandler
无法创建这个类的实例,可以使用StreamRequestHandler
和DataStreamRequestHandler
创建类的实例;StreamRequestHandler/DataStreamRequestHandler
tcp请求处理类的一个实现/udp请求处理类的一个实现;
socket线程池
附表
socket属性模块
服务器端套接字*通用函数
函数名 | 函数名 |
---|---|
s.bind() | 绑定地址(host,port)到套接字,在AF_INET下,以元组(host,port)的形式表示地址 |
s.listen() | 开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了 |
s.accept() | 被动接受TCP客户端连接,(阻塞式)等待连接的到来客户端套接字 |
s.connect() | 主动初始化TCP服务器连接,一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误 |
s.connect_ex() | 函数的扩展版本,出错时返回出错码,而不是抛出异常 |