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 }