I'm maintaining an embedded system that uses LwIP. The relevant code is as follows (edited):
iobSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
connectRC = connect(socket, &serverAddress, sizeof(struct sockaddr));
FD_SET(socket, &fdset);
selectRC = select((socket) 1, NULL, &fdset, NULL, &tv);
sendRC = send(iobSocket, dout, strlen(dout), 0);
This seems to work. When I remove the select() call, however, I get an error on the send() which sets errno to 119 or Connection already in progress. This error code isn't documented in the send() man pages.
Can someone tell me why the select() command is even necessary here, and why I might be getting an undocumented error without it?
Thank you.
CodePudding user response:
Error code 119 is EINPROGRESS
. It means the socket is operating in non-blocking mode 1, and the previous connect()
operation hasn't finished yet, which is why the send()
fails.
1: Which means, there must be more code that you are not showing, as sockets are normally in blocking mode when they are initially created, and require explicit code to put them into non-blocking mode, such as via fcntl(F_SETFL, O_NONBLOCK);
.
Using select()
to test the socket for writability allows your code to wait until the socket is actually done connecting and is ready for sending.
This is explained in the man page for connect()
:
RETURN VALUE
If the connection or binding succeeds, zero is returned. On error, -1 is returned, and
errno
is set to indicate the error.ERRORS
The following are general socket errors only. There may be other domain-specific error codes.
...
EINPROGRESS
The socket is nonblocking and the connection cannot be completed immediately. (UNIX domain sockets failed with EAGAIN instead.) It is possible toselect(2)
orpoll(2)
for completion by selecting the socket for writing. Afterselect(2)
indicates writability, usegetsockopt(2)
to read theSO_ERROR
option at levelSOL_SOCKET
to determine whetherconnect()
completed successfully (SO_ERROR
is zero) or unsuccessfully (SO_ERROR
is one of the usual error codes listed here, explaining the reason for the failure).