socket–Berkeley Socket,俗称套接字,实质是一套应用程序API(编程接口,对TCP/IP协议的封装,传输层/网络层协议,http是应用层协议)。主要功能是实现进程间通信,在网络通信中广泛应用。
# file: server.py
import socket
import select
# 创建socket, 使用ipv4协议(AF_INET), 流式协议
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("127.0.0.1", 64300)) # 绑定端口
server.listen(5) # 最大可支持5个客户端连接
print("server start ...")
while True:
# 接收连接并返回一个新的socket
# 当没有连接时将会阻塞在这里
conn, address = server.accept()
conn.send(b"Welcome to test server! \\n")
while True:
data = conn.recv(128)
if not data:
print("client disconnect")
conn.close()
break
else:
print(data)
# file: client.py
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
client.connect(("127.0.0.1", 64300))
except:
print("client connect fail")
raise ConnectionError
print("client connect")
client.send(b"Hello !")
data = client.recv(128)
if data:
print(data)
client.close()
print("client disconnect")
这里是最简单的一个socket编程示例,服务器启动之后阻塞在accept中等待连接,此时启动客户端往服务器建立连接并发送了一条消息,并获取来自服务器的返回,这里是双工通道(读和写互不影响,数据会被放在各自的缓冲区),之后关闭连接,随后服务器发现再也读取不到数据也关闭连接。
不过这里的服务器是阻塞式的,假设客户端A在建立连接之后不会立马退出,此时启动另一个客户端B,可以看到服务器端此时仍在内层循环循环读取A的数据,保持与A的通信,从而导致必须等到客户端A的连接关闭之后,客户端B的连接才能建立。也就是说一次只能有一个连接存在。
从上面的例子可以看出来,阻塞式的服务器无法满足多个客户端连接的需求,我们可以借助python中的select模块来实现多客户连接。