开发者

I have a question when i use read() in select

i have a question, when i use select() and read(). the key codes is : Collapse

nready = select( maxfd + 1, server->fd_readset, 0, 0, timeout );
       if( nready > 0 )
               printf( "nready is %d\n", nready );

       char buf[100];
       int n ;
       if ( FD_ISSET( server->fd , server->fd_readset ) )    /* new client connection */
       {
               int s = (int)accept( server->fd, 0, 0 );
               if ( s == -1 )
               {
                       printf( " errno is %d\n", errno );
                       fprintf( stdout, "error is %s\n", strerror( errno ) );
               }
               printf( "s is %d\n", s );
               for ( j = 0; j < FD_SETSIZE; j++ )
               {
                     开发者_运维技巧  if ( client[j] < 0 )
                       {
                               if( s > 0 )
                                       client[j] = s;  /* save descriptor */
                               break;
                       }
                }

        if ( j == FD_SETSIZE )
        {
                printf( "too much clients!\n" );
        }
        FD_SET( s, server->fd_set );    /* add new descriptor to set */
        if( s > maxfd )
                maxfd = s;      /* for select */
        if( j > maxi )
                maxi = j;       /* max index in client[] array */
        if( --nready <= 0 )
                continue;
}
for( j = 0; j <= maxi; j++ )
{
        if( ( sockfd = client[j] ) < 0 )
                continue;
        if( FD_SET( sockfd, server->fd_readset ) )
        {
                if( ( n = read( sockfd, buf, 100) ) != 0 )
                {

the question is: i start up the server, but i just let only one client send messages to server by function of write(). the another client can't send messages. i have debug by gdb, i found the server is blocking in read(); the server still read the first client. i try to use alarm() to solve it, but it don't work.when the read() make the time out, it's still blocking. please tell me why? thank you.


if( FD_SET( sockfd, server->fd_readset ) )

This line sets the descriptor in the readable set. Use FD_ISSET instead to test.


The problem may be that you haven't set the socket to non-blocking read mode. Your read will then wait until all 100 characters come in, which is probably not what you expect. If the client sends 32 bytes to the server, the server will wait in the read until 68 more bytes come in.

The problem is even more complicated than that. If you are in non-blocking mode, you may get partial reads. For example, the client may send 32 bytes to the server but the server may get only 10 in the first read. The server has to be smart enough to know that a partial message has been received and wait for the next 22 bytes.

The best way to deal with select and sockets is to have all file descriptors non-blocking, both read and write. It does complicate things quite a bit.


When using select(), you should mark all file descriptors non-blocking.

if (fcntl(s, F_SETFL, fcntl(s, F_GETFL, 0) | O_NONBLOCK) == -1) {
  perror("set socket nonblocking");
  exit(1);
}

You should also watch out for read() returning -1 with errno equal to EAGAIN, meaning no actual data available.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜