I am using non-blocking sockets to connect to a server.
In a specific test scenario, the server is down, which means a TCP SYN goes out, but there is no response and there can never be an established connection.
In this setup, usually select
times out after 2 seconds returning 0.
This is the behavior most of the time and it seems correct.
However, in roughly 5% of the cases, select
immediately returns 1 (indicating the socket is readable in the mask).
But when I read(2)
from the socket, -1
is returned with 'Network is unreachable
'
sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
// sockfd checked and > 0
// set non-blocking
struct timeval tv{};
tv.tv_sec = 2;
int ret = connect(sockfd, addr, addrlen ); // addr set elsewhere
if (ret < 0 && errno == EINPROGRESS)
{
fd_set cset;
FD_ZERO(&cset);
FD_SET(sockfd, &cset);
ret = select(sockfd + 1, &cset, nullptr, nullptr, &tv);
// returns 1 sometimes
}
In the first post, I incorrectly stated that in the error case, there is only one TCP SYN on the network (without retries).
This is not true; in both the error and non-error case, there is a TCP SYN on the network that is re-sent after 1 second.
What might cause this and is there a way to get consistent behavior with select
?