1. Socket 介绍
Socket套接字,是一种通用的网络编程接口,python中提供了socket.py标准库,非常底层的接口库。
接口相关参数:
- 协议族
- Socket类型
|
| 名称 | 含义 | | —- | —- | —- | | 协议族 | AF_INET | IPv4 | | | AF_INET6 | IPv6 | | Socket类型 | SOCK_STREAM | 面向连接的流套接字。默认值是TCP协议 | | | SOCK_DGRAM | 无连接的数据报文套接字。默认为UDP协议 |
Socket编程,一般需要两端,一个服务端Server,一个客户端Client。
2. TCP 编程
服务端编程步骤:
- 创建Socket对象;
- 绑定IP和端口;
- 开始监听
- 建链通信,获取用于传输数据的Socket对象
实现一个简单的TCP server:
import timeimport socket# TCP Serversock = socket.socket() # step1:创建Socket对象addr = ('127.0.0.1', 9999)sock.bind(addr) # step2: 绑定地址&端口sock.listen() # step3:开始监听time.sleep(10)sock.close() # step4:释放资源

使用工具模拟client,实现发送/接收消息:
import socketimport logginglogging.basicConfig(format='%(thread)s %(threadName)s %(message)s', level=logging.INFO)# TCP Serversock = socket.socket() # step1:创建Socket对象addr = ('127.0.0.1', 9999)sock.bind(addr) # step2: 绑定地址&端口sock.listen() # step3:开始监听conn, client_addr = sock.accept() # step4:完成三次握手,建立连接,下面就可以发送/接收数据了。默认是阻塞的,返回一个新对象logging.info(client_addr)# 接收消息data = conn.recv(1024)logging.info(data.decode())# 发送消息msg = 'ack: {}'.format(data.decode())conn.send(msg.encode())conn.close()sock.close()


client 模拟工具:
优化tcp server,实现一个连接发送/接收多次消息:
import socketimport logginglogging.basicConfig(format='[%(thread)s %(threadName)s] %(message)s', level=logging.INFO)# TCP Serversock = socket.socket()ip = '127.0.0.1'port = 9999addr = (ip, port)sock.bind(addr)sock.listen()conn, client_addr = sock.accept()while True:data = conn.recv(1024).decode()msg = "[ACK] {}".format(data)conn.send(msg.encode())if data == 'Disconnect':breakconn.close()sock.close()
注意:上面代码里的 accept() 、recv() 是阻塞性函数(此阻塞是一个I/O请求,或叫I/O密集性阻塞,等网络I/O的缓存区填满到你要求的时候,才可以继续执行后面的程序),主线程经常被阻塞住而不能工作,怎么办呢?
查看某个TCP进程端口的网络状态:netstat -ant | find “9999”


