As described in other posts, I'm trying to use select() in socket programming to detect closed connections. See the following code which tries to detect closed connections by select() and a following check on whether recv() returns 0. Before the while loop starts, there are two established TCP connections already. In our controlled experiment, the first connection always closes after about 15 seconds and the second about 30 seconds.
Theoretically (as described by others), when they get closed, select() should return (twice in our case) which allows us to detect both close events. The problem we face is that the select() now only returns once and never again, which allows us to detect ONLY the first connection close event. If the code for one IP it works fine but not for two or more connections.
Anyone has any ideas or suggestions? Thanks.
while (1)
{
printf("Waiting on select()...\n");
if ((result = select(max + 1, & readset, NULL, NULL, NULL)) < 0)
{
printf("select() failed");
break;
}
if (result > 0)
{
i=0;
while(i<max+1)
{
if (FD_ISSET(i, &readset))
{
result = recv(i, buffer, sizeof(buffer), 0);
if (result == 0)
{
close(i);
FD_CLR(i, &readset);
if (i == max)
{
max -= 1;
}
}
}
i++;
}
}
}
select()
modifies readset
to remove socket(s) that are not readable. Every time you call select()
, you have to reset and fill readset
with your latest list of active sockets that you want to test, eg:
fd_set readset;
int max;
while (1)
{
FD_ZERO(&readset);
max = -1;
// populate readset from list of active sockets...
// set max according...
printf("Waiting on select()...\n");
result = select(max + 1, &readset, NULL, NULL, NULL);
if (result < 0)
{
printf("select() failed");
break;
}
if (result == 0)
continue;
for (int i = 0; i <= max; ++i)
{
if (FD_ISSET(i, &readset))
{
result = recv(i, buffer, sizeof(buffer), 0);
if (result <= 0)
{
close(i);
// remove i from list of active sockets...
}
}
}
}