I have a blocking socket (at least it appears so in following code):
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
ERROR("%s: error opening socket", __func__);
return (RESP_ERROR);
}
t.tv_sec = timeout;
t.tv_usec = 0;
int rf = fcntl(sock, F_GETFD);
ERROR("fcntl ret=%d, ret & O_NONBLOCK = %d", rf, rf & O_NONBLOCK);
if ((setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&t, sizeof (t)) < 0)
|| (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&t, sizeof (t)))) {
strerror_r(errno, err, 254);
ERROR("%s: error on setsockopt -> %s", __func__, err);
close(sock);
return (RESP_ERROR);
}
rf = fcntl(sock, F_GETFD);
ERROR("after select fcntl ret=%d, ret & O_NONBLOCK = %d", rf, rf & O_NONBLOCK);
if (connect(sock, (struct sockaddr *)&dst, sizeof (dst)) != 0) {
strerror_r(errno, err, 254);
ERROR("%s: error on connect -> %s", __func__, err);
close(sock);
return (RESP_ERROR);
}
And this is from log:
Mar 6 10:42:04 tcpclient: fcntl ret=0, ret & O_NONBLOCK = 0
Mar 6 10:42:04 tcpclient: after select fcntl ret=0, ret & O_NONBLOCK = 0
Mar 6 10:42:14 tcpclient: authenticate: error on connect -> Operation now in progress
It appears this is a blocking socket but returns error typical for non-blocking? Linux is 2.6.18-308.el5. Any ideas?
If timeout
is not 0
the call to connect()
times out and returns. This happens independently of whether a connection was established or not.
From the moment the time-out expired connect()
behaves as if called on a non-blocking socket.
Referring this case (verbatim from man connect
and ignore "immediately" below):
EINPROGRESS
The socket is nonblocking and the connection cannot be completed immediately. It is possible to select(2) or poll(2) for completion by selecting the socket for writing. After select(2) indicates writability, use getsockopt(2) to read the SO_ERROR option at level SOL_SOCKET to determine whether connect() completed successfully (SO_ERROR is zero) or unsuccessfully (SO_ERROR is one of the usual error codes listed here, explain‐ ing the reason for the failure).
Btw: Could someone confirm this is standard behaviour, and for this explicitly mentioned somewhere?
man 7 socket
states (italics by me):
SO_RCVTIMEO and SO_SNDTIMEO
Specify the receiving or sending timeouts until reporting an error. [...] if no data has been transferred and the timeout has been reached then -1 is returned with errno set to EAGAIN or EWOULDBLOCK just as if the socket was specified to be nonblocking. [...] Timeouts only have effect for system calls that perform socket I/O (e.g., read(2), recvmsg(2), send(2), sendmsg(2)); timeouts have no effect for select(2), poll(2), epoll_wait(2), etc.
No word regarding connect()
so I'm unsure my answer does hold.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With