多次调用recv后,Python套接字发送不起作用

时间:2018-04-06 14:42:36

标签: python python-3.x sockets tcp

我正在使用TCP连接编写python代码来发送和接收数据。但我有一个问题,我觉得很困惑。当我在服务器套接字上调用recv方法一次然后发送时,它工作正常。但是,当我在服务器套接字上调用recv方法两次然后发送时,客户端不会从服务器接收任何内容但只是挂起。

这是服务器代码:

server = socket.socket()
server.bind(('0.0.0.0', 9999))
server.listen(5)
while True:
    client, addr = server.accept()
    client.recv(1024)
    # works if the line below is commented out
    client.recv(1024)
    client.send(b'ACK!')
    client.close()

以下是客户端代码:

client = socket.socket()
client.connect(('127.0.0.1', 9999))
client.send(bytes(sys.stdin.read(), encoding='utf-8'))
print(client.recv(4096).decode('utf-8'))

实际上,我计划在服务器代码中使用带有recv方法的循环。但是如果多次调用recv方法,则send方法不起作用。为什么会这样?

3 个答案:

答案 0 :(得分:1)

client.recv(1024)并不意味着阻塞,直到您接收1024个字节,此调用不能保证获得1024个字节,只能保证得到不超过 1024个字节。您可以获得0、9、25等个字节,仅不超过1024个字节。真正的问题是您的序列不太正确。在服务器端,您先调用recv 两次,然后发送;在客户端端,您先调用send 一次,然后接收。如果要在服务器上接收两次,则需要在客户端上发送两次。

问题在于您被阻止,因为您没有发送任何数据(在期望时)。

答案 1 :(得分:0)

我并不真的认为这是您的主要问题。您也没有指定连接类型(tcp或udp)。

对于TCP,您致电socket.socket(socket.SOCK_STREAM, socket.AF_INET)

对于UDP,您致电socket.socket(socket.SOCK_STREAM, socket.SOCK_DGRAM)

我不知道这是否可以解决您的问题,但我希望如此。

答案 2 :(得分:0)

当前给出的答案都无法解决您的问题。您的socket()构造可以使用默认参数,并且发送和接收的数量完全无关紧要。真正的答案是这样:

当您接收(1024)时,将至少获得一个 最多1024个字节。您可能知道后者,但前者可能会令人惊讶。这是网络如何工作的结果。 recv必须阻塞(除非套接字处于非阻塞模式),直到它得到 something ,并且事物至少为一个字节。因此,如果没有要阅读的内容,recv将挂起。它无法检测到这种情况与网络运行缓慢之间的差异。

如果您还有其他问题,请随时提问。