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 banner
112     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 grset
122     FD_SET(connfd,&grset);
123     maxfd = MAXOR(maxfd,connfd);
124 
125     //add client to gclients
126     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.socket
17     int sockfd;
18     if((sockfd = socket(PF_INET,SOCK_STREAM,0))<0)
19         ERR("socket failed");
20 
21     //3.connect
22     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 }

 

posted @ 2014-06-16 16:10  尾巴草  阅读(256)  评论(0编辑  收藏  举报