请问
1.此程序中的while(1)的作用是?
2. select是如何监视的文件描述符的变化情况呢? 
   不靠线程或者进程,它是怎么一直在监视呢?#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>int main()
{
    int server_sockfd, client_sockfd;
    int server_len, client_len;
    struct sockaddr_in server_address;
    struct sockaddr_in client_address;
    int result;
    fd_set readfds, testfds;/*  Create and name a socket for the server.  */    server_sockfd = socket(AF_INET, SOCK_STREAM, 0);    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = htonl(INADDR_ANY);
    server_address.sin_port = htons(9000);
    server_len = sizeof(server_address);    bind(server_sockfd, (struct sockaddr *)&server_address, server_len);/*  Create a connection queue and initialize readfds to handle input from server_sockfd.  */    listen(server_sockfd, 5);    FD_ZERO(&readfds);
    FD_SET(server_sockfd, &readfds);/*  Now wait for clients and requests.
    Since we have passed a null pointer as the timeout parameter, no timeout will occur.
    The program will exit and report an error if select returns a value of less than 1.  */    while(1) {
        char ch;
        int fd;
        int nread;
int writelen;

...
        testfds = readfds;        printf("server waiting\n");
        result = select(FD_SETSIZE, &testfds, (fd_set *)0,(fd_set *)0, (struct timeval *) 0);        switch(result) {
case 0:
printf("select time out");
break;
case -1:
printf("\n\nselect error\n");
exit(1);
        }/*  Once we know we've got activity,
    we find which descriptor it's on by checking each in turn using FD_ISSET.  */        for(fd = 0; fd < FD_SETSIZE; fd++) 
{
            if(FD_ISSET(fd,&testfds)) 
{
/*  If the activity is on server_sockfd, it must be a request for a new connection
    and we add the associated client_sockfd to the descriptor set.  */
                if(fd == server_sockfd) 
{
                    client_len = sizeof(client_address);
                    client_sockfd = accept(server_sockfd,(struct sockaddr *)&client_address, &client_len);
                    FD_SET(client_sockfd, &readfds);
                    printf("adding client on fd %d\n", client_sockfd);
                 }/*  If it isn't the server, it must be client activity.
    If close is received, the client has gone away and we remove it from the descriptor set.
    Otherwise, we 'serve' the client as in the previous examples.  */                else 
{
                    ioctl(fd, FIONREAD, &nread);
                    if(nread == 0) 
{
                        close(fd);
                        FD_CLR(fd, &readfds);
                        printf("removing client on fd %d\n", fd);
                     }                    else 
{
                        read(fd, &ch, 1);
                        sleep(2);
                        printf("serving client on fd %d\n", fd);
                        sleep(2); writelen=write(fd, buff, Len);
printf("\n\nwrite : %d\n\n",writelen);
if(writelen!=Len)
printf("write error!");
}
                 }
            }
        }
    }
}

解决方案 »

  1.   

    你这个select时间设置为0,应该是阻塞操作了。
      

  2.   

    select(FD_SETSIZE, &testfds, (fd_set *)0,(fd_set *)0, (struct timeval *) 0); 
    等待时间设置为 0  select()就没有等待功能了
      

  3.   

    select 通过fd_set数据结构,调用select时根据io状态修改fd_set 来通知执行那一个io 的套接口或文件描述符可用。
    主要是支持io复用 。最后一个参数是设定超时时间。select返回有三种情况,一是:readfds 有描述符可读,二是:writefds 中有描述符可写,三是:errorfds 中有描述符遇到错误,如果这三种情况都没有,select 会根据timeout 指定的超时时间返回。如果timeout 是空指针,select将一直阻塞。