UNIX TCP回射服务器/客户端(3):使用select模型的服务器

    《Unix网络编程》这本书附带了许多短小精美的小程序,我在阅读此书的时候,将书上的代码按照自己的理解重写了一遍(大部分是抄书上的),加深一下自己的理解(纯看书太困了,呵呵)。此例子在Ubuntu10.04上测试通过。

    PS:程序里使用了包裹函数(首字母是大写的函数)和常量(所有字母都是大写的常量)的声明在my_unp.h文件中,定义在unp_base.c和unp_thread.c中,地址:http://blog.csdn.net/aaa20090987/article/details/8096701

    程序简介:这是一个运用select函数进行IO复用的服务器模型。它的原理是:当一个客户端连接上服务器时,服务器就将其连接的fd加入fd_set集合,等到这个连接准备好读或写的时候,就通知程序进行IO操作,与客户端进行数据通信。它是一个经典的IO复用模型,但当同时连接的客户端数量变大时,fd_set集合就变得很大,而每次要时行IO操作时,都要遍历一次这个集合,导致效率降低,所以它现在基本上被EPOLL模型代替了。


上代码:

#include "my_unp.h"  
  
int main(void)  
{  
    int i, maxi, maxfd, listenfd, connfd, sockfd;  
    pid_t childpid;    
    int nready, client[FD_SETSIZE];  
    ssize_t n;  
    fd_set rset, allset;  
    char buf[MAXLINE];  
    socklen_t clilen;  
    struct sockaddr_in cliaddr, servaddr;  
  
    //创建用于TCP协议的套接字    
    listenfd = Socket(AF_INET, SOCK_STREAM, 0);  
    memset(&servaddr, 0, sizeof(servaddr));  
    servaddr.sin_family = AF_INET;  
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);  
    servaddr.sin_port = htons(SERV_PORT);  
  
    //把socket和socket地址结构联系起来   
    Bind(listenfd, (SA*)&servaddr, sizeof(servaddr));  
  
    //开始监听LISTENQ端口   
    Listen(listenfd, LISTENQ);  
  
    maxfd = listenfd;  
    maxi = -1;  
    //初始化结构fd_set  
    for(i=0; i maxfd )  
                maxfd = connfd;  
            if( i > maxi )  
                maxi = i;  
              
            //利用select的返回值来检查末就绪的描述符  
            if( --nready <= 0 )  
                continue;  
        }  
  
        //扫描每个现在客户链接  
        for(i=0; i<=maxi; i++)  
        {  
            sockfd = client[i];  
            if( sockfd < 0 )  
                continue;  
            if( FD_ISSET(sockfd, &rset) )  
            {  
                n = Read(sockfd, buf, MAXLINE);  
                //如果客户关闭了链接,就更新数据结构  
                if( 0 == n )  
                {  
                    Close(sockfd);  
                    FD_CLR(sockfd, &allset);  
                    client[i] = -1;  
                }  
                //否则,就回射一段字符给客户端  
                else  
                    Writen(sockfd, buf, n);  
            }  
  
            if( --nready <= 0 )  
                break;  
        }  
    }  
    return 0;  
}  
与其配套的客户端在这里:http://blog.csdn.net/aaa20090987/article/details/8462262

你可能感兴趣的:(UNIX TCP回射服务器/客户端(3):使用select模型的服务器)