http://blog.csdn.net/robertkun/article/details/52269313

参考:http://www.cnblogs.com/Anker/p/3261006.html

使用poll实现的io多路复用服务端和客户端。

客户端通过子进程创建多个客户端连接。

客户端每隔1秒向服务端发送一个时间戳,

服务端接收到时间戳以后,保存在本地的文件中,

一个客户端对应一个存储文件,

并将接收到的时间戳返回给客户端。

代码:

服务端:

[cpp] view plaincopy
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <fcntl.h>
  5. #include <poll.h>
  6. #include <errno.h>
  7. #include <unistd.h>
  8. #include <sys/ioctl.h>
  9. #include <sys/types.h>
  10. #include <sys/socket.h>
  11. #include <sys/stat.h>
  12. #include <netinet/in.h>
  13. #include <arpa/inet.h>
  14. #define IP_ADDR     "127.0.0.1"
  15. #define PORT        59999
  16. #define LISTEN_Q    5
  17. #define OPEN_MAX    100000
  18. #define INFTIM      -1
  19. #define MAX_LINE    1024
  20. static int socket_bind(const char* ip, int port);
  21. static void do_poll(int ln_fd);
  22. static void handle_conn(struct pollfd* conn_fds, int num, int* files);
  23. int main()
  24. {
  25. int ln_fd, cn_fd, sk_fd = 0;
  26. struct sockaddr_in _addr;
  27. socklen_t _len;
  28. ln_fd = socket_bind(IP_ADDR, PORT);
  29. listen(ln_fd, LISTEN_Q);
  30. do_poll(ln_fd);
  31. return 0;
  32. }
  33. static int socket_bind(const char* ip, int port)
  34. {
  35. int ln_fd;
  36. struct sockaddr_in _addr;
  37. ln_fd = socket(AF_INET, SOCK_STREAM, 0);
  38. if(ln_fd == -1) {
  39. perror("socket error!");
  40. exit(1);
  41. }
  42. bzero(&_addr, sizeof(_addr));
  43. _addr.sin_family = AF_INET;
  44. inet_pton(AF_INET, ip, &_addr.sin_addr);
  45. _addr.sin_port = htons(port);
  46. if(bind(ln_fd, (struct sockaddr*)&_addr, sizeof(_addr)) == -1) {
  47. perror("bind error!");
  48. exit(1);
  49. }
  50. return ln_fd;
  51. }
  52. static void do_poll(int ln_fd)
  53. {
  54. int connfd, sockfd = 0;
  55. struct sockaddr_in _addr;
  56. socklen_t _len;
  57. int files[OPEN_MAX];
  58. struct pollfd clients[OPEN_MAX];
  59. int nMax, i, nReady = 0;
  60. clients[0].fd = ln_fd;
  61. clients[0].events = POLLIN;
  62. for(i = 1; i<OPEN_MAX; ++i) {
  63. clients[i].fd = -1;
  64. }
  65. nMax = 0;
  66. while(1) {
  67. nReady = poll(clients, nMax+1, INFTIM);
  68. if(nReady == -1) {
  69. perror("poll error!");
  70. exit(1);
  71. }
  72. else {
  73. printf("poll ready num = %d\n", nReady);
  74. }
  75. if(clients[0].revents & POLLIN) {
  76. _len = sizeof(_addr);
  77. if((connfd = accept(ln_fd, (struct sockaddr*)&_addr, &_len)) == -1) {
  78. if(errno == EINTR) {
  79. printf("EINTR!\n");
  80. continue;
  81. }
  82. else {
  83. perror("accept error!");
  84. exit(1);
  85. }
  86. }
  87. fprintf(stdout, "accept a new client! [%s]\n", inet_ntoa(_addr.sin_addr));
  88. for(i=1; i<OPEN_MAX; ++i) {
  89. if(clients[i].fd < 0) {
  90. fcntl(connfd, F_SETFL, fcntl(connfd,F_GETFL)| O_NONBLOCK);
  91. unsigned long nVal=1;
  92. ioctl(connfd, FIONBIO, &nVal);
  93. clients[i].fd = connfd;
  94. char path[2048] = {"\0"};
  95. getcwd(path, sizeof(path));
  96. sprintf(path, "%s/tmp_%d.txt", path, i);
  97. printf("path=%s\n", path);
  98. int fd = open(path, O_RDWR|O_APPEND|O_CREAT, 0666);
  99. if(fd > 0) {
  100. files[i] = fd;
  101. }
  102. else {
  103. fprintf(stdout, "open file error! [%s]\n", path);
  104. perror("open file error!");
  105. }
  106. break;
  107. }
  108. }
  109. fflush(stdout);
  110. if(i == OPEN_MAX) {
  111. fprintf(stderr, "too many clients\n");
  112. exit(1);
  113. }
  114. clients[i].events = POLLIN;
  115. nMax = (i > nMax ? i : nMax);
  116. if(--nReady <= 0) {
  117. printf("nReady = %d, nMax = %d\n", nReady, nMax);
  118. continue;
  119. }
  120. }
  121. handle_conn(clients, nMax, files);
  122. }
  123. }
  124. static void handle_conn(struct pollfd* conn_fds, int num, int* files)
  125. {
  126. int i, n = 0;
  127. char buf[MAX_LINE];
  128. memset(buf, 0, MAX_LINE);
  129. for(i=1; i<=num; ++i)
  130. {
  131. if(conn_fds[i].fd < 0)
  132. continue;
  133. if(conn_fds[i].revents & POLLIN) {
  134. n = read(conn_fds[i].fd, buf, MAX_LINE);
  135. if(n == 0) {
  136. close(conn_fds[i].fd);
  137. conn_fds[i].fd = -1;
  138. continue;
  139. }
  140. write(files[i], buf, n);
  141. write(conn_fds[i].fd, buf, n);
  142. }
  143. }
  144. }

客户端:

[cpp] view plaincopy
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <sys/types.h>
  6. #include <sys/socket.h>
  7. #include <netinet/in.h>
  8. #include <poll.h>
  9. #include <errno.h>
  10. #include <arpa/inet.h>
  11. #define MAX_LINE    1024
  12. #define IP_ADDR     "127.0.0.1"
  13. #define SERV_PORT   59999
  14. #define max(a,b) (a>b)?a:b
  15. static void do_conn();
  16. static void handle_conn(int sockfd);
  17. int main(int args, char* argv[])
  18. {
  19. int i = 0;
  20. for(i=0; i<2000; ++i) {
  21. pid_t fpid = -1;
  22. fpid = fork();
  23. if(fpid < 0) {
  24. printf("error in fork!");
  25. }
  26. else if(fpid == 0) {
  27. do_conn();
  28. }
  29. else {
  30. //do_conn();
  31. }
  32. }
  33. return 0;
  34. }
  35. static void do_conn()
  36. {
  37. int sockfd;
  38. struct sockaddr_in _addr;
  39. sockfd = socket(AF_INET, SOCK_STREAM, 0);
  40. bzero(&_addr, sizeof(_addr));
  41. _addr.sin_family = AF_INET;
  42. _addr.sin_port = htons(SERV_PORT);
  43. inet_pton(AF_INET, IP_ADDR, &_addr.sin_addr);
  44. int ret = connect(sockfd, (struct sockaddr*)&_addr, sizeof(_addr));
  45. if(ret < 0) {
  46. perror("connect failed!");
  47. exit(1);
  48. }
  49. handle_conn(sockfd);
  50. }
  51. static void handle_conn(int sockfd)
  52. {
  53. char send_line[MAX_LINE] = {'\0'};
  54. char recv_line[MAX_LINE] = {'\0'};
  55. struct pollfd pfds[1];
  56. pfds[0].fd = sockfd;
  57. pfds[0].events = POLLIN|POLLOUT;
  58. while(1) {
  59. poll(pfds, 1, 1000);
  60. if(pfds[0].revents & POLLIN) {
  61. int ret = read(sockfd, recv_line, MAX_LINE);
  62. if(ret == 0) {
  63. perror("client: server is closed.");
  64. close(sockfd);
  65. continue;
  66. }
  67. else if(ret < 0) {
  68. perror("client: read error!");
  69. continue;
  70. }
  71. //printf("[%d] recv=%s\n", (int)getpid(), recv_line);
  72. }
  73. if(pfds[0].revents & POLLOUT) {
  74. time_t _time = time(0);
  75. char dt[20]={"\0"};
  76. sprintf(dt, "%d\n", _time);
  77. memcpy(send_line, dt, strlen(dt));
  78. int ret = write(sockfd, send_line, strlen(send_line));
  79. if(ret < 0) {
  80. perror("write error!!");
  81. }
  82. }
  83. sleep(1);
  84. }
  85. shutdown(sockfd, SHUT_WR);
  86. }

使用poll实现的io多路复用服务端和客户端相关推荐

  1. php io select,Python IO多路复用之——select方案服务端和客户端代码【python源码详解】...

    准备文件: IO.py  服务端代码 tcp_c.py 客户端代码 IO.py 代码: from select import * #引入 select 模块 from socket import * ...

  2. SpringBoot(23) 集成socket.io服务端和客户端实现通信

    一.前言 websocket和socket.io区别? websocket 一种让客户端和服务器之间能进行双向实时通信的技术 使用时,虽然主流浏览器都已经支持,但仍然可能有不兼容的情况 适合用于cli ...

  3. 模拟QQ聊天小项目收尾---界面展示服务端与客户端进行信息交互(用到的知识:io,线程,Swing界面,面向对象思想...... )

    大家好,我是一位在java学习圈中不愿意透露姓名并苟且偷生的小学员,如果文章有错误之处,还望海涵,欢迎多多指正 如果你从本文学到有用的干货知识,那么请您尽量点赞,关注,评论,收藏 这两天我一直在设计这 ...

  4. socket.io服务端是java_SpringBoot(23) 集成socket.io服务端和客户端实现通信

    @Slf4j @Service(value = "socketIOService") public class SocketIOServiceImpl implements ISo ...

  5. web 服务端与客户端交互

    Web server to client communication Technology 1.   Traditional solution 传统模式的 Web 系统以客户端发出请求.服务器端响应的 ...

  6. 服务端向客户端主动发送消息

    通常情况下,无论是web浏览器还是移动app,我们与服务器之间的交互都是主动的,客户端向服务器端发出请求,然后服务器端返回数据给客户端,客户端浏览器再将信息呈现,客户端与服务端对应的模式是: 客户端请 ...

  7. 【计算机网络】服务端和客户端最大支持多少tcp连接?如何分析?

    文章目录 (一)引用文章 (二)简单分析: 1.基本概念:TCP四元组 2.多个客户端连接一个服务端最大支持最大多少tcp连接? 3.一个客户端连接一个服务端最大支持多少个tcp连接? (二)全面分析 ...

  8. java sslsocket程序_JAVA与C++进行sslsocket通信,JAVA做服务端或客户端

    前几天有位网友问我关于Unity3D里面使用Protobuf的方法,一时有事拖到现在才写这篇文章,不好意思哈. 本文测试环境: 系统:WINDOWS 7(第3.6步).OS X 10.9(第4步) 软 ...

  9. netty tcp服务端主动断开客户端_【Netty】服务端和客户端

    欢迎关注公众号:[爱编程] 如果有需要后台回复2019赠送1T的学习资料哦!! 本文是基于Netty4.1.36进行分析 服务端 Netty服务端的启动代码基本都是如下: private void s ...

最新文章

  1. android里面画布快照,自定义 View - Canvas - 画布操作和快照
  2. 解决IE6下 position的fixed定位问题
  3. UI调试--初步尝试心得总结
  4. Web应用进行XSS漏洞测试
  5. oracle100多g满了,Oracle11g ORA-00257归档日志满问题处理
  6. 如何设置word的有效期
  7. mini6410 LED驱动程序及LED测试程序的设计
  8. 电脑桌面有计算机和回收站怎么办,电脑回收站不见了怎么办 电脑回收站找回的4种方法...
  9. KALI2021安装teemo的一些问题
  10. IT人的求职技巧 中山大学新炬网络校园宣讲会
  11. Chrome浏览器怎么安装插件
  12. php-cli和php-fpm的关系是什么?
  13. 攻防世界007 伪造xff_referer
  14. Java软件工程师[初级测试题]
  15. 百度地图经纬度与腾讯地图经纬度之间的转换
  16. python tcp黏包和struct模块解决方法,大文件传输方法及MD5校验
  17. Win10任务栏重启无数次都在转圈卡死解决方法(超级简单)
  18. form表单如何加css框架,如何写好CSS系列之表单(form)
  19. Compound-Fault Diagnosis of Rotating Machinery: A Fused Imbalance Learning Method
  20. 世界500强企业优秀员工的十二条核心标准

热门文章

  1. 以A表中的值快速更新B表中记录的方法
  2. Hive中的数据库、表、数据与HDFS的对应关系
  3. iframe高度自适应,终于解决了
  4. java 获取随机数字的三种方法
  5. 将 JAR 转为 EXE – JSMOOTH 的使用教程(第二期)(转载)
  6. hdu--4902--线段树
  7. linux 命令案例学习——文件搜索
  8. 端口如何支持非localhost访问_新特性解读 | MySQL 8.0.19 支持 DNS SRV
  9. 自动论文生成器 python_Python生成器常见问题及解决方案
  10. 不存在_施文忠 | ”存在“与“不存在”——巴蜀文明概论