I am designing a turn-based game that uses connection.recv() to read from the socket and store the data of a 'move' in a buffer (which the server reads from). The problem is, the player can send data outside of their turn to be queued in the socket buffer, which means the server potentially reads from moves they made outside of their turn, instead of blocking until they make a turn. Is there any way to flush the data stored in the socket, and if not, is there any other workaround to this problem?
Asked
Active
Viewed 652 times
0
-
Have you check out this [question](https://stackoverflow.com/questions/4407835/python-socket-flush)? – Gealber May 09 '21 at 09:34
-
Yes. Unfortunately I can't use a makefile object, as it would mean closing the socket (on the client side) to read from the makefile on the server side, which wouldn't work in a game such as this. – Allen Antony May 09 '21 at 10:03
-
If you want to make sure that no data were send before they are allowed you can recv and discard all the data before turning - recv and discard is basically emptying the buffer. You can also do a challenge-response scheme, i.e. the server explicitly gives a random token to the client only when it is the clients turn and the client need to send the token back when doing their turn. – Steffen Ullrich May 09 '21 at 10:10
-
Hi, I tried using recv to clear the buffer and it worked! I'm currently setting the socket to non-blocking and using a BlockingIOError exception to detect if there is nothing left to read. Is there a more graceful approach to this problem? – Allen Antony May 09 '21 at 10:37
-
"I can't use a makefile object, as it would mean closing the socket ... to read ... on the server side". No, just call `.flush()` on the client side after writing to the makefile. – Mark Tolonen May 10 '21 at 05:29
1 Answers
2
From Steffen's suggestion, I am using recv calls to clear the buffer. Currently, I'm setting the socket to non-blocking and calling recv until a BlockingIOError. It would be much appreciated if anyone could point out a more graceful solution (that doesn't use exceptions).
connection.setblocking(False)
while True:
try:
chunk = connection.recv(4096)
except BlockingIOError as b:
break
connection.setblocking(True)

Allen Antony
- 23
- 3