Python套接字等待

6

我想知道是否有一种方法可以让Python等待直到接收到服务器的响应才继续运行。

我正在编写一个回合制游戏。我做出第一步,然后它将移动发送到服务器,然后再发送给另一台电脑。问题就在这里。由于现在轮到对手了,我希望我的游戏等待直到从服务器接收到响应(等待对手进行移动)。但是我的代码行:

data=self.sock.recv(1024)

程序卡住了(我认为)是因为没有立即获取到某些东西。因此,我想知道如何让它等待某些事件的发生,然后继续执行。

提前感谢。


“Crashes”?你遇到了什么错误?能提供一下 traceback 吗? - A. Jesse Jiryu Davis
1
好的,它会冻结,没有回溯。我必须强制关闭窗口,然后它会显示:“进程以退出代码-805306369结束”@A。 - mapl93
2个回答

2
这句话的翻译是:“socket programming howto与此问题相关,特别是其中的这一部分:”。”
现在我们来到了套接字的主要难点 - send和recv操作网络缓冲区。它们不一定处理您提供给它们的所有字节(或者您期望从它们那里得到的所有字节),因为它们的主要重点是处理网络缓冲区。通常情况下,当相关联的网络缓冲区已填满(send)或已清空(recv)时,它们会返回。然后告诉您它们处理了多少字节。您需要负责再次调用它们,直到您的消息被完全处理为止。
还有一个需要注意的复杂情况:如果您的对话协议允许连续发送多个消息(而不需要某种回复),并且您传递给recv一个任意大小的块,您可能会读取到以下消息的开头。您需要将其放在一边,并保留它,直到需要使用它。
在消息前加上长度(比如5个数字字符)会变得更加复杂,因为您可能无法在一个recv中获得所有5个字符。在尝试中,您可能能够成功;但在高网络负载下,除非使用两个recv循环 - 第一个用于确定长度,第二个用于获取消息的数据部分,否则您的代码将很快崩溃。这很糟糕。这也是您将发现send并不能总是在一次传输中成功处理所有内容的时候。尽管已经阅读了这篇文章,您最终仍将受到其影响!
这段话的主要要点是:
  • 你需要设定一个固定的消息大小或在消息开头发送消息大小

  • 在调用socket.recv时,传递你实际需要的字节数(我猜你并不需要1024个字节)。然后使用循环,因为不能保证一次调用能获取到所有你需要的数据。


1
那行代码 sock.recv(1024) 会阻塞直到接收到1024个字节或操作系统检测到套接字错误。你需要知道消息大小的方法——这就是为什么HTTP消息包括Content-Length的原因。
你可以使用 socket.settimeout 设置超时时间,如果预期的字节数在超时之前没有到达,则完全中止读取。
你还可以使用 setblocking(0) 探索Python的非阻塞套接字。

11
.recv 可能会返回少于 1024 字节的数据。 - jfs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接