生活随笔
收集整理的這篇文章主要介紹了
使用poll实现的io多路复用服务端和客户端
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
http://blog.csdn.net/robertkun/article/details/52269313
參考:http://www.cnblogs.com/Anker/p/3261006.html
使用poll實現的io多路復用服務端和客戶端。
客戶端通過子進程創建多個客戶端連接。
客戶端每隔1秒向服務端發送一個時間戳,
服務端接收到時間戳以后,保存在本地的文件中,
一個客戶端對應一個存儲文件,
并將接收到的時間戳返回給客戶端。
代碼:
服務端:
[cpp]?view plaincopy
#include?<stdio.h>?? #include?<stdlib.h>?? #include?<string.h>?? #include?<fcntl.h>?? #include?<poll.h>?? #include?<errno.h>?? #include?<unistd.h>?? ?? #include?<sys/ioctl.h>?? #include?<sys/types.h>?? #include?<sys/socket.h>?? #include?<sys/stat.h>?? ?? #include?<netinet/in.h>?? #include?<arpa/inet.h>?? ?? ?? #define?IP_ADDR?????"127.0.0.1"?? #define?PORT????????59999?? #define?LISTEN_Q????5?? #define?OPEN_MAX????100000?? #define?INFTIM??????-1?? #define?MAX_LINE????1024?? ?? static?int?socket_bind(const?char*?ip,?int?port);?? static?void?do_poll(int?ln_fd);?? static?void?handle_conn(struct?pollfd*?conn_fds,?int?num,?int*?files);?? ?? int?main()?? {?? ????int?ln_fd,?cn_fd,?sk_fd?=?0;?? ????struct?sockaddr_in?_addr;?? ?? ????socklen_t?_len;?? ????ln_fd?=?socket_bind(IP_ADDR,?PORT);?? ????listen(ln_fd,?LISTEN_Q);?? ?? ????do_poll(ln_fd);?? ????return?0;?? }?? ?? ?? static?int?socket_bind(const?char*?ip,?int?port)?? {?? ????int?ln_fd;?? ????struct?sockaddr_in?_addr;?? ????ln_fd?=?socket(AF_INET,?SOCK_STREAM,?0);?? ????if(ln_fd?==?-1)?{?? ????????perror("socket?error!");?? ????????exit(1);?????????? ????}?? ?? ????bzero(&_addr,?sizeof(_addr));?? ????_addr.sin_family?=?AF_INET;?? ????inet_pton(AF_INET,?ip,?&_addr.sin_addr);?? ????_addr.sin_port?=?htons(port);?? ?? ????if(bind(ln_fd,?(struct?sockaddr*)&_addr,?sizeof(_addr))?==?-1)?{?? ????????perror("bind?error!");?? ????????exit(1);?? ????}?? ?? ????return?ln_fd;?? }?? ?? static?void?do_poll(int?ln_fd)?? {?? ????int?connfd,?sockfd?=?0;?? ????struct?sockaddr_in?_addr;?? ????socklen_t?_len;?? ????int?files[OPEN_MAX];?? ????struct?pollfd?clients[OPEN_MAX];?? ????int?nMax,?i,?nReady?=?0;?? ?????? ????clients[0].fd?=?ln_fd;?? ????clients[0].events?=?POLLIN;?? ?????? ????for(i?=?1;?i<OPEN_MAX;?++i)?{?? ????????clients[i].fd?=?-1;?? ????}?? ????nMax?=?0;?? ?? ????while(1)?{?? ????????nReady?=?poll(clients,?nMax+1,?INFTIM);?? ????????if(nReady?==?-1)?{?? ????????????perror("poll?error!");?? ????????????exit(1);?? ????????}?? ????????else?{?? ????????????printf("poll?ready?num?=?%d\n",?nReady);?? ????????}?? ?? ????????if(clients[0].revents?&?POLLIN)?{?? ????????????_len?=?sizeof(_addr);?? ????????????if((connfd?=?accept(ln_fd,?(struct?sockaddr*)&_addr,?&_len))?==?-1)?{?? ????????????????if(errno?==?EINTR)?{?? ????????????????????printf("EINTR!\n");?? ????????????????????continue;?? ????????????????}?? ????????????????else?{?? ????????????????????perror("accept?error!");?? ????????????????????exit(1);?? ????????????????}?? ????????????}?? ?? ????????????fprintf(stdout,?"accept?a?new?client!?[%s]\n",?inet_ntoa(_addr.sin_addr));?? ?? ????????????for(i=1;?i<OPEN_MAX;?++i)?{?? ????????????????if(clients[i].fd?<?0)?{?? ????????????????????fcntl(connfd,?F_SETFL,?fcntl(connfd,F_GETFL)|?O_NONBLOCK);?? ????????????????????unsigned?long?nVal=1;?? ????????????????????ioctl(connfd,?FIONBIO,?&nVal);?? ?? ????????????????????clients[i].fd?=?connfd;?? ????????????????????char?path[2048]?=?{"\0"};?? ????????????????????getcwd(path,?sizeof(path));?? ?????????????????????? ????????????????????sprintf(path,?"%s/tmp_%d.txt",?path,?i);?? ????????????????????printf("path=%s\n",?path);?? ????????????????????int?fd?=?open(path,?O_RDWR|O_APPEND|O_CREAT,?0666);?? ????????????????????if(fd?>?0)?{?? ????????????????????????files[i]?=?fd;?? ????????????????????}?? ????????????????????else?{?? ????????????????????????fprintf(stdout,?"open?file?error!?[%s]\n",?path);?? ????????????????????????perror("open?file?error!");?? ????????????????????}?? ?? ????????????????????break;?? ????????????????}?? ????????????}?? ?? ????????????fflush(stdout);?? ?? ????????????if(i?==?OPEN_MAX)?{?? ????????????????fprintf(stderr,?"too?many?clients\n");?? ????????????????exit(1);?? ????????????}?? ?? ????????????clients[i].events?=?POLLIN;?? ????????????nMax?=?(i?>?nMax???i?:?nMax);?? ????????????if(--nReady?<=?0)?{?? ????????????????printf("nReady?=?%d,?nMax?=?%d\n",?nReady,?nMax);?? ????????????????continue;?? ????????????}?? ????????}?? ?????????? ????????handle_conn(clients,?nMax,?files);?? ????}?? }?? ?? static?void?handle_conn(struct?pollfd*?conn_fds,?int?num,?int*?files)?? {?? ????int?i,?n?=?0;?? ????char?buf[MAX_LINE];?? ????memset(buf,?0,?MAX_LINE);?? ????for(i=1;?i<=num;?++i)?? ????{?? ????????if(conn_fds[i].fd?<?0)?? ????????????continue;?? ?? ????????if(conn_fds[i].revents?&?POLLIN)?{?? ????????????n?=?read(conn_fds[i].fd,?buf,?MAX_LINE);?? ????????????if(n?==?0)?{?? ????????????????close(conn_fds[i].fd);?? ????????????????conn_fds[i].fd?=?-1;?? ????????????????continue;?? ????????????}?? ?? ????????????write(files[i],?buf,?n);?? ????????????write(conn_fds[i].fd,?buf,?n);?? ????????}?? ????}?? }??
客戶端:
[cpp]?view plaincopy
#include?<stdio.h>?? #include?<stdlib.h>?? #include?<string.h>?? ?? #include?<unistd.h>?? #include?<sys/types.h>?? #include?<sys/socket.h>?? ?? #include?<netinet/in.h>?? #include?<poll.h>?? #include?<errno.h>?? #include?<arpa/inet.h>?? ?? #define?MAX_LINE????1024?? #define?IP_ADDR?????"127.0.0.1"?? #define?SERV_PORT???59999?? ?? #define?max(a,b)?(a>b)?a:b?? ?? static?void?do_conn();?? static?void?handle_conn(int?sockfd);?? ?? int?main(int?args,?char*?argv[])?? {?? ????int?i?=?0;?? ????for(i=0;?i<2000;?++i)?{?? ????????pid_t?fpid?=?-1;?? ????????fpid?=?fork();?? ????????if(fpid?<?0)?{?? ????????????printf("error?in?fork!");?? ????????}?? ????????else?if(fpid?==?0)?{?? ????????????do_conn();?? ????????}?? ????????else?{?? ?????????????? ????????}?? ????}?? ?? ????return?0;?? }?? ?? static?void?do_conn()?? {?? ????int?sockfd;?? ????struct?sockaddr_in?_addr;?? ????sockfd?=?socket(AF_INET,?SOCK_STREAM,?0);?? ?? ????bzero(&_addr,?sizeof(_addr));?? ????_addr.sin_family?=?AF_INET;?? ????_addr.sin_port?=?htons(SERV_PORT);?? ?? ????inet_pton(AF_INET,?IP_ADDR,?&_addr.sin_addr);?? ????int?ret?=?connect(sockfd,?(struct?sockaddr*)&_addr,?sizeof(_addr));?? ????if(ret?<?0)?{?? ????????perror("connect?failed!");?? ????????exit(1);?? ????}?? ?? ????handle_conn(sockfd);?? }?? ?? static?void?handle_conn(int?sockfd)?? {?? ????char?send_line[MAX_LINE]?=?{'\0'};?? ????char?recv_line[MAX_LINE]?=?{'\0'};?? ?? ????struct?pollfd?pfds[1];?? ????pfds[0].fd?=?sockfd;?? ????pfds[0].events?=?POLLIN|POLLOUT;?? ?? ????while(1)?{?? ????????poll(pfds,?1,?1000);?? ????????if(pfds[0].revents?&?POLLIN)?{?? ????????????int?ret?=?read(sockfd,?recv_line,?MAX_LINE);?? ????????????if(ret?==?0)?{?? ????????????????perror("client:?server?is?closed.");?? ????????????????close(sockfd);?? ????????????????continue;?? ????????????}?? ????????????else?if(ret?<?0)?{?? ????????????????perror("client:?read?error!");?? ????????????????continue;?? ????????????}?? ?? ?????????????? ????????}?? ?? ????????if(pfds[0].revents?&?POLLOUT)?{?? ????????????time_t?_time?=?time(0);?? ????????????char?dt[20]={"\0"};?? ????????????sprintf(dt,?"%d\n",?_time);?? ?? ????????????memcpy(send_line,?dt,?strlen(dt));?? ????????????int?ret?=?write(sockfd,?send_line,?strlen(send_line));?? ????????????if(ret?<?0)?{?? ????????????????perror("write?error!!");?? ????????????}?? ????????}?? ?? ????????sleep(1);?? ????}?? ?? ????shutdown(sockfd,?SHUT_WR);?? }??
總結
以上是生活随笔為你收集整理的使用poll实现的io多路复用服务端和客户端的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。