【问题标题】:Python socket send not working after calling recv more than once多次调用recv后Python套接字发送不起作用
【发布时间】:2018-09-16 15:10:11
【问题描述】:

我正在编写 python 代码来发送和接收数据,使用 TCP 连接。但是我有一个问题,我觉得很困惑。当我在服务器套接字上调用一次 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 方法就不起作用。为什么会这样?

【问题讨论】:

  • 服务器端client.recv(1024) 可能被阻塞等待数据。你预计会发生什么?
  • @JamesKPolk 我希望服务器接收所有数据(因此第二次调用 recv 将不会收到任何数据)然后发送数据。但正如您所说,服务器可能正在等待recv 的第二次调用中的数据。我想我可能需要使用settimeout。谢谢你的回答。

标签: python python-3.x sockets tcp


【解决方案1】:

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

当您recv(1024) 时,您将获得至少一个,并且最多1024 个字节。你可能知道后者,但前者可能是一个惊喜。这是网络工作方式的结果。 recv 必须阻塞(除非套接字处于非阻塞模式)直到它得到 something,并且该东西将至少是一个字节。因此,如果没有可读取的内容,recv 将挂起。它无法检测到这种情况与网络速度慢之间的区别。

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

【讨论】:

    【解决方案2】:

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

    对于 TCP,您调用 socket.socket(socket.SOCK_STREAM, socket.AF_INET)

    对于 UDP,您调用 socket.socket(socket.SOCK_STREAM, socket.SOCK_DGRAM)

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

    【讨论】:

      【解决方案3】:

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

      问题是你被阻止了,因为你没有发送任何数据,而当它期待某些东西时。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-14
        • 1970-01-01
        • 2018-09-12
        • 2016-09-29
        • 2013-07-13
        • 1970-01-01
        相关资源
        最近更新 更多