开发者

TCP client socket, doesn't block on select()

The following code is a test program wriiten to understand the behaviour of select() call in a TCP client program.

What I observe is that the select is not blocking, instead the program is b开发者_开发技巧locking on recv(). The output is as follows:

Wait on select.
Wait on recv.
...

My question is why the select() returns a success? Ideally it should be blocking on the select() instead of recv().

The TCP server is sending a character string of 15 bytes once in 3 seconds.

int clientfd = -1;
int dummyfd = -1;
int maxfd = -1;
struct sockaddr_in server_addr;

char recv_buf[100] = {0};
int msg_len = 0;
int bytes_recv = 0;
fd_set readfd;
int retval = 0;


/* Open the socket and a dummy socket */.
clientfd = socket(AF_INET, SOCK_STREAM, 0);
dummyfd = socket(AF_INET, SOCK_STREAM, 0);
if(-1 == clientfd || -1 == dummyfd)
{
    perror("socket error: ");
    exit(1);
}
printf("Socket opened : %d\n", clientfd);

server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(10000);
//server_addr.sin_addr.s_addr = INADDR_ANY;
inet_aton("127.0.0.1", &(server_addr.sin_addr));
memset(&(server_addr.sin_zero), 0, 8);

/* Connect to server */
if(connect(clientfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)))
{
    perror("connect error: ");
    exit(1);
}
printf("Connect Success\n");
maxfd = (clientfd > dummyfd) ? (clientfd + 1) : (dummyfd + 1);
while(1)
{
    FD_ZERO(&readfd);
    FD_SET(clientfd, &readfd);
    FD_SET(dummyfd, &readfd);
    printf("Wait on select\n");
    retval = select(maxfd , &readfd, NULL, NULL, NULL);
    if(retval <= 0)
    {
        printf("select failed\n");
    }
    else
    {
            printf("Wait on recv\n");
            /* ... The process waits here ... */
            bytes_recv = recv(clientfd, recv_buf, 100, 0);
            printf("%d: Bytes recv = %d\t%s\n", retval, bytes_recv, recv_buf);
            memset(recv_buf, 0 ,100);
    }
}

close(clientfd);
return 0;
}

Edit: Without dummyfd, the program works as intended. A follow up question:

When the server is closed abruptly, how to detect this using select()?

Can the program be modified so that is blocks on select() when the server side, say, crashes?


Use the following to be sure it's the clientfd that's returning from the select:

else if (FD_ISSET(clientfd, &readfd)) {

Don't have time to test, but I suspect the dummyfd is returning as an EOF from the select, not the clientfd.


After select() returns, you will want to conditionally receive from clientfd. My guess is that there may be data on dummyfd that is triggering the select to complete, but the receive is on the clientfd.

retval = select(maxfd , &readfd, NULL, NULL, NULL);
if(retval <= 0)
{
    printf("select failed\n");
}
else
{
    if (FD_ISSET(clientfd, &readfd))
    {
        bytes_recv = recv(clientfd, recv_buf, 100, 0);
        ...
    }

    if (FD_ISSET(dummyfd, &readfd))
    {
        /* "dummyfd" processing */
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜