Python Socket阻塞和非阻塞
Socket是一个在网络编程中常用的工具,它提供了一种实现网络通信的方法。在Python中,我们可以使用socket库来创建和管理Socket。在网络通信中,通常会遇到阻塞和非阻塞两种不同的模式。本文将介绍Python Socket的阻塞和非阻塞模式,并提供相应的代码示例。
1. Socket阻塞模式
在Socket阻塞模式下,当我们调用一个阻塞式的Socket方法时,程序会一直等待,直到操作完成或超时。在这种模式下,当我们进行网络通信时,程序会停止执行,直到接收或发送完成。
示例代码
import socket
# 创建Socket对象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 12345))
server_socket.listen(1)
# 阻塞式等待客户端连接
print("等待客户端连接...")
client_socket, addr = server_socket.accept()
print("客户端已连接:", addr)
# 阻塞式接收数据
print("等待接收数据...")
data = client_socket.recv(1024)
print("接收到的数据:", data.decode())
# 阻塞式发送数据
print("发送数据中...")
client_socket.send("Hello, Client!".encode())
# 关闭Socket连接
client_socket.close()
server_socket.close()
在上面的代码中,我们创建了一个服务器Socket对象,并使用accept()
方法阻塞等待客户端的连接。接下来,我们使用recv()
方法阻塞式地接收客户端发送的数据,并使用send()
方法阻塞式地发送响应数据。
在阻塞模式下,当Socket对象执行accept()
、recv()
或send()
等方法时,程序会停止在这里等待,直到操作完成或超时。这种模式下的网络通信是一种同步的方式,只有完成当前操作后才能继续执行后续代码。
2. Socket非阻塞模式
相对于阻塞模式,Socket的非阻塞模式允许我们在进行网络通信时,程序可以同时执行其他任务,而不是一直等待操作完成。在非阻塞模式下,Socket对象的方法会立即返回,不管操作是否完成。
示例代码
import socket
# 创建Socket对象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 12345))
server_socket.listen(1)
# 设置非阻塞模式
server_socket.setblocking(False)
# 非阻塞式等待客户端连接
while True:
try:
client_socket, addr = server_socket.accept()
print("客户端已连接:", addr)
break
except BlockingIOError:
pass
# 非阻塞式接收数据
data = b""
while True:
try:
chunk = client_socket.recv(1024)
if chunk:
data += chunk
else:
break
except BlockingIOError:
pass
print("接收到的数据:", data.decode())
# 非阻塞式发送数据
while True:
try:
client_socket.send("Hello, Client!".encode())
break
except BlockingIOError:
pass
# 关闭Socket连接
client_socket.close()
server_socket.close()
在上面的代码中,我们首先创建了一个服务器Socket对象,并使用setblocking(False)
方法将其设置为非阻塞模式。接下来,我们使用一个无限循环来不断尝试接收客户端的连接,直到成功连接为止。在接收数据和发送数据的过程中,我们同样使用无限循环来持续尝试操作,直到操作成功为止。
在非阻塞模式下,当Socket对象执行accept()
、recv()
或send()
等方法时,程序会立即返回,不会等待操作完成。因此,我们需要使用循环来不断尝试操作,直到操作成功。
3. 阻塞与非阻塞模式的对比
下面是阻塞和非阻塞模式的对比表格:
阻塞模式 | 非阻塞模式 | |
---|---|---|
连接 |