select服务器

来源:互联网 发布:java pfx证书读取 编辑:程序博客网 时间:2024/05/14 14:13
#include<stdio.h>#include<sys/socket.h>#include<sys/types.h>#include<netinet/in.h>#include<arpa/inet.h>#include<sys/select.h>#include<stdlib.h>#include<unistd.h>int fds[sizeof(fd_set)*8];static void usage(const char *proc){    printf("%s [local_ip] [local_port]\n",proc);}int startup(const char *ip,int port){    int sock = socket(AF_INET,SOCK_STREAM,0);    if(sock < 0)    {        perror("sock");        exit(2);    }    int opt = 1;    setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));    struct sockaddr_in local;    local.sin_family = AF_INET;    local.sin_port = htons(port);    local.sin_addr.s_addr = inet_addr(ip);    if(bind(sock,(struct sockaddr*)&local,sizeof(local)) < 0)    {        perror("bind");        exit(3);    }    if(listen(sock,10) < 0)    {        perror("listen");        exit(4);    }    return sock;}int main(int argc,char *argv[]){    if(argc != 3)    {        usage(argv[0]);        return 1;    }    int listen_sock = startup(argv[1],atoi(argv[2]));// listen a link just like care read events    int nums = sizeof(fds)/sizeof(fds[0]);    int i = 0;//set array start_value    for(;i < nums;++i)    {        fds[i] = -1;    }        fds[0] = listen_sock;     fd_set rfds;     while(1)    {        int maxfd = -1;        struct timeval timeout = {2,0};        FD_ZERO(&rfds);        i = 0;        for(;i < nums;++i)  //set fd_set and find maxfd        {            if(fds[i] == -1)            {                continue;            }            FD_SET(fds[i],&rfds);            if(maxfd < fds[i])            {                maxfd = fds[i];            }        }               switch(select(maxfd+1,&rfds,NULL,NULL,NULL))        {            case -1:            break;            case 0:            printf("timeout....\n");            break;            default://at least one fd ready            {                i = 0;                for(;i < nums;++i)                {                    if(i == 0&&FD_ISSET(fds[i],&rfds))//have ready,can start to accept                    {                        struct sockaddr_in client;                        socklen_t len = sizeof(client);                        int new_socket = accept(listen_sock,(struct sockaddr*)&client,&len);//can not blocked                        if(new_socket < 0)                        {                            perror("accept");                            continue;                        }                        printf("get a client: [%s:%d]\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));                        int j = 1;                        for(;j < nums;++j)                        {                            if(fds[j] == -1)   //find a position for new_socket,if new_socket ready,start to write/read                            {                                break;                            }                        }                            if(j == nums)                            {                                close(new_socket); //the fd_set is full,can not handler this link,close it                            }                            else                            {                                fds[j] = new_socket;                            }                                         }                    else if(i != 0&&FD_ISSET(fds[i],&rfds)) //new_socket ready ,start to write/read ,not be blocked                    {                        char buf[1024];                        ssize_t s = read(fds[i],buf,sizeof(buf)-1);                         if(s > 0)                        {                            buf[s] = 0;                            printf("client#%s\n",buf);                        }                        else if(s == 0)                        {                            printf("client is quit!!!\n");                            close(fds[i]);  //not only close this link                            fds[i] = -1;  //but also set the array,next run do not care the fds                        }                        else                        {                            perror("read");                            close(fds[i]);                            fds[i] = -1;                        }                    }                }            }        }    }    return 0;}

原创粉丝点击