原文地址:https://www.zhblog.net/go/python/advanced/python-socket-selectors?t=563
Socket API 是用来通过网络传递信息的,也为进程间通信提供一种形式。
最常见的 socket 程序就是 client-server 应用程序,下面在同一主机上进程之间进行通信。
首先,了解 socket 的 server 端和 client 端 api。
Socket API
Python 的 socket 模块提供了 socket api 的接口。
主要的方法:
socket()
bind()
listen()
accept()
connect()
connect_ex()
send()
recv()
close()
python 提供了直接映射到操作系统的 api(底层C),保证了方便与一致性。
TCP Socket
使用 socket.socket() 创建一个 socket 对象,并指定 socket 类型为 socket.SOCK_STREAM,这就默认我们使用的协议为 TCP,在通常情况下,这就是我们想要使用的。
TCP 协议优点:
可靠性:发送者会检测网络传输中是否丢包,并重发在网络中丢掉的数据包。
顺序发送:数据被读取时保证数据是发送者写的顺序。
另外,UDP socket 可以指定为 socket.SOCK_DGRAM,它与 TCP 相反,数据传输不可靠且无序。
下图中,可以明确看出 socket api 调用和 TCP 传输
图左边表示服务端,右边是客户端。
左边最上面四个方法:
socket():创建 socket
bind():绑定主机和端口
listen():监听客户端连接
accept():当客户端请求连接时,建立连接
客户端调用 connect() 与服务端建立连接并启动三次握手,握手可以确定网络双方是否可以彼此到达。简而言之,服务端可以到达客户端,客户端可以到达服务端。
中间的 send() 和 recv() 就是服务端与客户端进行数据交换。
最下面 close() 关闭各自的 socket。
Server-Client 程序
现在已经了解了 socket API 和 server 与 client 是如何通信的,接下来就做一个简单的实现:服务端返回从客户端接收的任何内容。
服务端 server.py:
import socket
import time
HOST = '127.0.0.1'
PORT = 8888
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
data = conn.recv(1024)
print(data, 'time:', time.time())
if not data:
break
conn.sendall(data)
socket.socket() 是以 context manager 的形式创建一个 socket 对象,这样不用显示调用 s.close()。传递的参数是地址族(address family)和 socket 类型。AF_INET 表示 IPv4 的网络地址族,SOCK_STREAM 表示是 TCP 协议的 socket。
bind() 用指定的网络接口和端口关联 sock