简体   繁体   English

Python套接字等待

[英]Python socket wait

I was wondering if there is a way I can tell python to wait until it gets a response from a server to continue running.我想知道是否有一种方法可以告诉 python 等待它从服务器获得响应以继续运行。

I am writing a turn based game.我正在写一个回合制游戏。 I make the first move and it sends the move to the server and then the server to the other computer.我进行了第一步,它将移动发送到服务器,然后将服务器发送到另一台计算机。 The problem comes here.问题来了。 As it is no longer my turn I want my game to wait until it gets a response from the server (wait until the other player makes a move).由于不再轮到我,我希望我的游戏等到它得到服务器的响应(等到其他玩家采取行动)。 But my line:但我的线路:

data=self.sock.recv(1024)

hangs because (I think) it's no getting something immediately.挂起是因为(我认为)它没有立即得到一些东西。 So I want know how can I make it wait for something to happen and then keep going.所以我想知道如何让它等待某些事情发生然后继续前进。

Thanks in advance.提前致谢。

That line, sock.recv(1024) , blocks until 1024 bytes have been received or the OS detects a socket error.该行sock.recv(1024)阻塞,直到接收到 1024 个字节或操作系统检测到套接字错误。 You need some way to know the message size -- this is why HTTP messages include the Content-Length.您需要某种方式来了解消息大小——这就是 HTTP 消息包含 Content-Length 的原因。

You can set a timeout with socket.settimeout to abort reading entirely if the expected number of bytes doesn't arrive before a timeout.如果预期的字节数在超时之前没有到达,您可以使用socket.settimeout设置超时以完全中止读取。

You can also explore Python's non-blocking sockets using setblocking(0).您还可以使用 setblocking(0) 探索 Python 的非阻塞套接字。

The socket programming howto is relevant to this question, specifically this part: socket编程howto与这个问题有关,特别是这部分:

Now we come to the major stumbling block of sockets - send and recv operate on the network buffers.现在我们来到了套接字的主要绊脚石——send 和 recv 在网络缓冲区上操作。 They do not necessarily handle all the bytes you hand them (or expect from them), because their major focus is handling the network buffers.它们不一定处理您交给它们(或期望它们)的所有字节,因为它们的主要重点是处理网络缓冲区。 In general, they return when the associated network buffers have been filled (send) or emptied (recv).通常,当关联的网络缓冲区已填充(发送)或清空(接收)时,它们会返回。 They then tell you how many bytes they handled.然后他们会告诉你他们处理了多少字节。 It is your responsibility to call them again until your message has been completely dealt with.您有责任再次致电他们,直到您的消息得到完全处理。

... ...

One complication to be aware of: if your conversational protocol allows multiple messages to be sent back to back (without some kind of reply), and you pass recv an arbitrary chunk size, you may end up reading the start of a following message.需要注意的一个复杂问题:如果您的对话协议允许多条消息背靠背发送(没有某种回复),并且您向 recv 传递了任意块大小,则您最终可能会读取以下消息的开头。 You'll need to put that aside >and hold onto it, until it's needed.你需要把它放在一边>并抓住它,直到需要它。

Prefixing the message with it's length (say, as 5 numeric characters) gets more complex, because (believe it or not), you may not get all 5 characters in one recv.用它的长度(例如,作为 5 个数字字符)作为消息前缀变得更加复杂,因为(信不信由你),您可能无法在一次接收中获得所有 5 个字符。 In playing around, you'll get away with it;在玩耍时,你会侥幸逃脱; but in high network loads, your code will very quickly break unless you use two recv loops - the first to determine the length, the second to get the data part of the message.但是在高网络负载下,除非您使用两个 recv 循环 - 第一个确定长度,第二个用于获取消息的数据部分,否则您的代码将很快中断。 Nasty.可恶的。 This is also when you'll discover that send does not always manage to get rid of everything in one pass.这也是您会发现 send 并不总是能够一次性清除所有内容的时候。 And despite having read this, you will eventually get bit by it!尽管阅读了这篇文章,您最终还是会被它吸引住!

The main takeaways from this are:主要结论是:

  • you'll need to establish either a FIXED message size, OR you'll need to send the the size of the message at the beginning of the message您需要建立固定的消息大小,或者您需要在消息的开头发送消息的大小

  • when calling socket.recv, pass number of bytes you actually want (and I'm guessing you don't actually want 1024 bytes).调用 socket.recv 时,传递您实际想要的字节数(我猜您实际上并不想要 1024 字节)。 Then use LOOPs because you are not guaranteed to get all you want in a single call.然后使用 LOOP,因为您不能保证在一次调用中获得所有想要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM