为什么 socket.recv() 有时会阻塞,有时不会?
Why is socket.recv() sometimes blocking and sometimes not?
我正在尝试制作一个客户端-服务器应用程序,其中:
- 客户端向服务器发送消息(函数名称)
- 服务端收到消息,调用相应的函数并将结果returns发送给客户端。
只有当来自客户端的消息是一个时,我才能这样做;如果我想调用两个或更多函数,并因此发送两个或更多消息,我会遇到一些问题,因为我需要在服务器内添加一个循环。
特别是socket函数recv()我不太清楚。通常,为了接收数据,我会写这样的东西(没有 setblocking())而且我从来没有遇到过任何问题:
while True:
data = sock.recv(BUFFER)
results += data.decode()
if not data:
break
但是如果我向服务器添加一个while True:
(为了等待其他函数),那么客户端永远不会退出sock.rev()。为什么?我希望该函数根据其设置方式始终阻塞或始终非阻塞 sock.setblocking().
我已经尝试过 settimeout() 并且它有效,但是性能真的很重要所以我想避免所有可能的延迟。
无论如何,主要问题是为什么 recv() 的行为不同;如果您对解决我的任务有任何建议,我们将不胜感激。
下面是对实际应用的简单模拟。
客户:
import socket
BUFFER = 1024
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address= ('localhost', 14000)
sock.connect(bridge_address)
msg1 = "function 1".encode()
msg2 = "function 2".encode()
results1 = " "
results2 = " "
sock.sendall(msg1)
while True:
data = sock.recv(BUFFER)
results1 += data.decode()
if not data:
print('no more data')
break
sock.sendall(msg2)
while True:
data = sock.recv(BUFFER)
results2 += data.decode()
if not data:
print('no more data')
break
sock.close()
print('Results 1: ',results1)
print('Results 2: ',results2)
服务器:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('localhost', 14000)
sock.bind(server_address)
sock.listen(1)
msg = ""
for i in range(4096):
msg += str(i) + " "
while True:
print('waiting for a connection')
client, client_address = sock.accept()
try:
while True:
data = client.recv(128)
if not data:
print('no more data from')
break
client.sendall(msg.encode())
finally:
print('connection closed.\n')
client.close()
您明确强制服务器端套接字接收来自客户端的消息,即使客户端没有发送任何内容。
data = client.recv(128)
if not data:
print('no more data from')
break
if
上面代码片段中的情况只会在客户端套接字关闭时执行。
解决此问题的一种方法是首先发送消息的大小,然后针对指定的字节数相应地调用 recv
。
我正在尝试制作一个客户端-服务器应用程序,其中:
- 客户端向服务器发送消息(函数名称)
- 服务端收到消息,调用相应的函数并将结果returns发送给客户端。
只有当来自客户端的消息是一个时,我才能这样做;如果我想调用两个或更多函数,并因此发送两个或更多消息,我会遇到一些问题,因为我需要在服务器内添加一个循环。
特别是socket函数recv()我不太清楚。通常,为了接收数据,我会写这样的东西(没有 setblocking())而且我从来没有遇到过任何问题:
while True:
data = sock.recv(BUFFER)
results += data.decode()
if not data:
break
但是如果我向服务器添加一个while True:
(为了等待其他函数),那么客户端永远不会退出sock.rev()。为什么?我希望该函数根据其设置方式始终阻塞或始终非阻塞 sock.setblocking().
我已经尝试过 settimeout() 并且它有效,但是性能真的很重要所以我想避免所有可能的延迟。 无论如何,主要问题是为什么 recv() 的行为不同;如果您对解决我的任务有任何建议,我们将不胜感激。
下面是对实际应用的简单模拟。
客户:
import socket
BUFFER = 1024
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address= ('localhost', 14000)
sock.connect(bridge_address)
msg1 = "function 1".encode()
msg2 = "function 2".encode()
results1 = " "
results2 = " "
sock.sendall(msg1)
while True:
data = sock.recv(BUFFER)
results1 += data.decode()
if not data:
print('no more data')
break
sock.sendall(msg2)
while True:
data = sock.recv(BUFFER)
results2 += data.decode()
if not data:
print('no more data')
break
sock.close()
print('Results 1: ',results1)
print('Results 2: ',results2)
服务器:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('localhost', 14000)
sock.bind(server_address)
sock.listen(1)
msg = ""
for i in range(4096):
msg += str(i) + " "
while True:
print('waiting for a connection')
client, client_address = sock.accept()
try:
while True:
data = client.recv(128)
if not data:
print('no more data from')
break
client.sendall(msg.encode())
finally:
print('connection closed.\n')
client.close()
您明确强制服务器端套接字接收来自客户端的消息,即使客户端没有发送任何内容。
data = client.recv(128)
if not data:
print('no more data from')
break
if
上面代码片段中的情况只会在客户端套接字关闭时执行。
解决此问题的一种方法是首先发送消息的大小,然后针对指定的字节数相应地调用 recv
。