首页 > 代码库 > Socket编程之Select模型

Socket编程之Select模型

echoserver_select.c

  1 #include <apue.h>  2   3 #define BACKLOG 10  4 #define PORT 8080  5 #define MAXCLIENT 20  6 #define LEN_BUF 255  7   8 fd_set grset;  9 int maxfd; 10 struct client 11 { 12     char ip[16]; 13     unsigned short port; 14     int connfd; 15 }; 16  17 struct client *gclients[MAXCLIENT]; 18 int curclient; 19  20 void readclient(int index); 21 void acceptnewconnection(int sockfd); 22  23 int main(int argc,char **argv) 24 { 25     //1.socket 26     int sockfd; 27     if((sockfd = socket(PF_INET,SOCK_STREAM,0))<0) 28         ERR("socket failed"); 29      30     //2.reuseaddr 31     int val = 1; 32     if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&val,sizeof(val))<0) 33         ERR("set reuse addr failed"); 34      35     //3.bind 36     struct sockaddr_in ipv4; 37     CLEAR(ipv4); 38     ipv4.sin_family = AF_INET; 39     ipv4.sin_port = htons(PORT); 40     ipv4.sin_addr.s_addr = htonl(INADDR_ANY); 41  42     if(bind(sockfd,(struct sockaddr*)&ipv4,sizeof(ipv4))<0) 43         ERR("bind failed"); 44      45     //4.listen 46     listen(sockfd,BACKLOG); 47  48     fd_set rset; 49     FD_ZERO(&grset); 50     FD_SET(sockfd,&grset); 51     maxfd = MAXOR(maxfd,sockfd); 52  53     while(1) 54     { 55         rset = grset; 56         if(select(maxfd+1,&rset,NULL,NULL,NULL)<0) 57             ERR("select failed"); 58         if(FD_ISSET(sockfd,&rset)) 59         { 60             acceptnewconnection(sockfd); 61         } 62         int i; 63         for(i=0;i<MAXCLIENT;i++) 64         { 65             if(gclients[i]==NULL) 66                 continue; 67             if(FD_ISSET(gclients[i]->connfd,&rset)) 68             { 69                 readclient(i); 70             } 71         } 72     } 73  74     return 0; 75 } 76  77 void readclient(int index) 78 { 79     struct client *clp; 80     clp = gclients[index]; 81     char buf[LEN_BUF]; 82     int n; 83     if((n = read(clp->connfd,buf,sizeof(buf)))<0) 84         ERR("write failed"); 85     else if(n==0) 86     { 87         printf("Connection is closed by peer!\n"); 88         close(clp->connfd); 89         FD_CLR(clp->connfd,&grset); 90         free(clp); 91         gclients[index] = NULL; 92         curclient--; 93     } 94     else 95     { 96         if(write(clp->connfd,buf,n)<0) 97             ERR("write failed"); 98     } 99 }100 101 void acceptnewconnection(int sockfd)102 {103     if(curclient==MAXCLIENT)104         return;105     int connfd;106     struct sockaddr_in peer;107     socklen_t len;108     if((connfd = accept(sockfd,(struct sockaddr*)&peer,&len))<0)109         ERR("accept failed");110 111     //send banner112     unsigned short peerport = ntohs(peer.sin_port);113     char ipstr[] = "ddd.ddd.ddd.ddd";114     inet_ntop(AF_INET, &peer.sin_addr, ipstr, sizeof(ipstr));115     char banner[255];116     sprintf(banner, "[%s:%d] welcome to echoserver!", ipstr,peerport);117     printf("Accept a new Connection: %s,%d\n",ipstr,peerport);118     if(write(connfd, banner, strlen(banner)) < strlen(banner))119         ERR("write failed");120     121     //add connfd to grset122     FD_SET(connfd,&grset);123     maxfd = MAXOR(maxfd,connfd);124 125     //add client to gclients126     struct client *clp;127     clp = malloc(sizeof(struct client));128     if(clp==NULL)129         exit(-1);130     strcpy(clp->ip,ipstr);131     clp->port = peerport;132     clp->connfd = connfd;133 134     int i;135     for(i=0;i<MAXCLIENT;i++)136     {137         if(gclients[i]==NULL)138         {139             gclients[i] = clp;140             break;141         }142     }143     curclient++;144 }

echoclient.c

 1 #include <apue.h> 2  3 void do_business(int sockfd); 4  5 int main(int argc,char **argv) 6 {     7     //1.判断命令行 8     if(argc!=3) 9     {10         printf("Usage: %s <host> <port>\n",argv[0]);11         exit(0);12     }13     char *ipstr = argv[1];14     unsigned short port = strtol(argv[2],NULL,10);15 16     //2.socket17     int sockfd;18     if((sockfd = socket(PF_INET,SOCK_STREAM,0))<0)19         ERR("socket failed");20 21     //3.connect22     struct hostent *ent;23     if((ent=gethostbyname(ipstr))==NULL)24         ERR("gethostbyname failed");25 26     struct sockaddr_in peer;27     CLEAR(peer);28     peer.sin_family = AF_INET;29     peer.sin_port = htons(port);30     //inet_pton(AF_INET,ipstr,&peer.sin_addr);31     memcpy(&peer.sin_addr,ent->h_addr,sizeof(struct in_addr));32     if(connect(sockfd,(struct sockaddr*)&peer,sizeof(peer))<0)33         ERR("connect failed");34 35     //4.交互36     char banner[255];37     int n;38     if((n = read(sockfd,banner,sizeof(banner)))<0)39         ERR("read failed");40     else if(n==0)41         goto end;42     banner[n] = 0;43     printf("%s\n",banner);44 45     do_business(sockfd);46 47     //5.关闭48 end:49     close(sockfd);50 51     return 0;52 }53 54 void do_business(int sockfd)55 {56     int n;57     char buf[255],msg[255];58     while(1)59     {60         printf("shell# ");61         fflush(stdout);62         scanf("%s",buf);63         if(write(sockfd,buf,strlen(buf))<0)64             ERR("write failed");65         if((n = read(sockfd,msg,sizeof(msg)))<0)66             ERR("read failed");67         else if(n==0)68             break;69         msg[n] = 0;70         printf("%s\n",msg);71     }72 }