2

I'm having an issue with Python's socket module that I haven't been able to find anywhere else.

I'm building a simple TCP chat client, and while it successfully connects to the server initially, the script hangs endlessly on sock.recv() despite the fact that I explicitly set a timeout length.

I've tried using different timeout values and including setblocking(False) but no matter what I do it keeps acting like the socket is in blocking mode.

Here are the relevant parts of my code:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
def listen_to_server():
 global connected
 while connected:
 ready_to_read, ready_to_write, in_error = select.select([sock], [], [])
 if ready_to_read:
 try:
 data = sock.recv(1024)
 except socket.timeout:
 print('TIMEOUT')
 if not data:
 append_to_log('Disconnected from server.\n')
 connected = False
 else:
 append_to_log(str(data))

Any suggestions would be helpful, I'm at a total loss here.

asked Jul 11, 2017 at 16:27
6
  • I'm not sure why the timeout isn't working, but your first if-statement should be: if sock in ready_to_read: Commented Jul 11, 2017 at 16:29
  • I'm wondering, is socket.bind() not supposed to be called at some point? Commented Jul 11, 2017 at 16:35
  • Also, if you're using a timeout, then the socket is supposed to be in blocking mode. Commented Jul 11, 2017 at 16:37
  • @Dziugas I believe socket.bind() is for the server side. For the client I use socket.connect() which I omitted from the snippet because I didn't think it was relevant. Also I was under the impression that blocking mode implied that the program halted until data was received from the socket, sans timeout. Commented Jul 11, 2017 at 16:41
  • @JeremyFriesner Thanks for the tip! Commented Jul 11, 2017 at 16:43

1 Answer 1

2

You've mixed two things the socket timeout and the select.

When you set socket timeout then you are telling to that socket: if I try do some operation (e.g. recv()) and it won't be finished until my limit then raise timeout exception.

The select takes file descriptors (on Windows only sockets) and start checking if the rlist (the first parameter) contains any socket ready to read (aka some data have arrived). If any data arrived then the program continues.

Now your code do this:

  1. Set timeout for socket operations
  2. Select start waiting for data (if you don't send them then they never arrives)

and that's it. You stuck at the select.

You should just call the recv() without select. Than your timeout should be applied.

If you need manage multiple sockets at once than you have to use select and set the 4th parameter timeout.

answered Jul 11, 2017 at 16:47
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.