How can I determine if a non-blocking socket is really connected?
networking, nonblocking, python, sockets
Solution
Try checking the return values. Here's what I get in a similar situation:
>>> import socket, errno, os, time, select
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> sock.setblocking(0)
>>> err = sock.connect_ex(('10.0.0.1', 12345))
>>> import errno
>>> print errno.errorcode[err]
EINPROGRESS
>>> print sock.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
61
>>> print errno.errorcode[61]
ECONNREFUSED
The `select()` call is probably returning because there was an exceptional condition on the socket - that is, its connection was refused.
If I do this, the `select()` returns immediately:
>>> ready_to_read, ready_to_write, in_error = select.select([], [sock], [])
And interestingly enough, the return values match exactly what you passed in (if you had more than one socket, that would likely be different):
>>> print in_error
[]
>>> print ready_to_read
[]
>>> print ready_to_write
[<socket._socketobject object at 0x10ccd0980>]
The designers of `select()` are expecting you to run `select()` in a loop, and if a socket returns an error when you attempt the write, remove it from the list when the write fails.
So you have a couple of options, off the top of my head:
- Wait until you try to read the socket and fail, then take the appropriate action.
- Use `getsockopt()` as I did above to check if the socket is OK, or is in an error state, before attempting to do anything with it.
Problem
This question is not limited to Python. Its a general socket question. I have a non-blocking socket and want to connect to a machine which is reachable - on the other side the port does not exist. Why does select(...) succeed anyway? I expected a timeout. sock.send(...) fails with a broken pipe. How can I determine if the socket is really connected after select(...)? Thanks in advance. ``` import socket, errno, os, time, select sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setblocking(0) err = sock.connect_ex(('192.168.178.21', 12345)) ready_to_read, ready_to_write, in_error = select.select([], [sock], [], timeout=5) #ready_to_write is set even 192.168.178.21:12345 does not exist. sock.setblocking(1) sock.send('foo') #this fails sock.close() ```