Python socket wait

2019-06-24 05:12发布

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.

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.

2条回答
做个烂人
2楼-- · 2019-06-24 06:09

That line, sock.recv(1024), blocks until 1024 bytes have been received or the OS detects a socket error. You need some way to know the message size -- this is why HTTP messages include the 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.

You can also explore Python's non-blocking sockets using setblocking(0).

查看更多
啃猪蹄的小仙女
3楼-- · 2019-06-24 06:11

The socket programming howto is relevant to this question, specifically this part:

Now we come to the major stumbling block of sockets - send and recv operate on the network buffers. 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. 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. 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. Nasty. This is also when you’ll discover that send does not always manage to get rid of everything in one pass. 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). Then use LOOPs because you are not guaranteed to get all you want in a single call.

查看更多
登录 后发表回答