https://blog.csdn.net/lianghe_work/article/details/46535859

想详细彻底地了解poll或看懂下面的代码请参考《Linux网络编程——I/O复用之poll函数》

代码:

  1. #include <string.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <sys/select.h>
  6. #include <sys/time.h>
  7. #include <sys/socket.h>
  8. #include <netinet/in.h>
  9. #include <arpa/inet.h>
  10. #include <poll.h>
  11. #include <errno.h>
  12. #define OPEN_MAX 100
  13. int main(int argc, char *argv[])
  14. {
  15. //1.创建tcp监听套接字
  16. int sockfd = socket(AF_INET, SOCK_STREAM, 0);
  17. //2.绑定sockfd
  18. struct sockaddr_in my_addr;
  19. bzero(&my_addr, sizeof(my_addr));
  20. my_addr.sin_family = AF_INET;
  21. my_addr.sin_port = htons(8000);
  22. my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  23. bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr));
  24. //3.监听listen
  25. listen(sockfd, 10);
  26. //4.poll相应参数准备
  27. struct pollfd client[OPEN_MAX];
  28. int i = 0, maxi = 0;
  29. for(;i<OPEN_MAX; i++)
  30. client[i].fd = -1;//初始化poll结构中的文件描述符fd
  31. client[0].fd = sockfd;//需要监测的描述符
  32. client[0].events = POLLIN;//普通或优先级带数据可读
  33. //5.对已连接的客户端的数据处理
  34. while(1)
  35. {
  36. int ret = poll(client, maxi+1, -1);//对加入poll结构体数组所有元素进行监测
  37. //5.1监测sockfd(监听套接字)是否存在连接
  38. if((client[0].revents & POLLIN) == POLLIN )
  39. {
  40. struct sockaddr_in cli_addr;
  41. int clilen = sizeof(cli_addr);
  42. int connfd = 0;
  43. //5.1.1 从tcp完成连接中提取客户端
  44. connfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
  45. //5.1.2 将提取到的connfd放入poll结构体数组中,以便于poll函数监测
  46. for(i=1; i<OPEN_MAX; i++)
  47. {
  48. if(client[i].fd < 0)
  49. {
  50. client[i].fd = connfd;
  51. client[i].events = POLLIN;
  52. break;
  53. }
  54. }
  55. //5.1.3 maxi更新
  56. if(i > maxi)
  57. maxi = i;
  58. //5.1.4 如果没有就绪的描述符,就继续poll监测,否则继续向下看
  59. if(--ret <= 0)
  60. continue;
  61. }
  62. //5.2继续响应就绪的描述符
  63. for(i=1; i<=maxi; i++)
  64. {
  65. if(client[i].fd < 0)
  66. continue;
  67. if(client[i].revents & (POLLIN | POLLERR))
  68. {
  69. int len = 0;
  70. char buf[128] = "";
  71. //5.2.1接受客户端数据
  72. if((len = recv(client[i].fd, buf, sizeof(buf), 0)) < 0)
  73. {
  74. if(errno == ECONNRESET)//tcp连接超时、RST
  75. {
  76. close(client[i].fd);
  77. client[i].fd = -1;
  78. }
  79. else
  80. perror("read error:");
  81. }
  82. else if(len == 0)//客户端关闭连接
  83. {
  84. close(client[i].fd);
  85. client[i].fd = -1;
  86. }
  87. else//正常接收到服务器的数据
  88. send(client[i].fd, buf, len, 0);
  89. //5.2.2所有的就绪描述符处理完了,就退出当前的for循环,继续poll监测
  90. if(--ret <= 0)
  91. break;
  92. }
  93. }
  94. }
  95. return 0;
  96. }

运行结果:

Linux网络编程——tcp并发服务器(poll实现)相关推荐

  1. Linux网络编程——tcp并发服务器(多进程)

    https://blog.csdn.net/lianghe_work/article/details/46503895 一.tcp并发服务器概述 一个好的服务器,一般都是并发服务器(同一时刻可以响应多 ...

  2. Linux网络编程——tcp并发服务器(多线程)

    https://blog.csdn.net/lianghe_work/article/details/46504243 tcp多线程并发服务器 多线程服务器是对多进程服务器的改进,由于多进程服务器在创 ...

  3. Linux网络编程——tcp并发服务器(epoll实现)

    https://blog.csdn.net/lianghe_work/article/details/46551871 通过epoll实现tcp并发回执服务器(客户端给服务器发啥,服务器就给客户端回啥 ...

  4. Linux网络编程——tcp并发服务器(I/O复用之select)

    https://blog.csdn.net/lianghe_work/article/details/46519633 与多线程.多进程相比,I/O复用最大的优势是系统开销小,系统不需要建立新的进程或 ...

  5. Linux网络编程——tcp并发服务器(I/O复用之select

    http://blog.csdn.net/lianghe_work/article/details/46519633 与多线程.多进程相比,I/O复用最大的优势是系统开销小,系统不需要建立新的进程或者 ...

  6. 【Linux网络编程】并发服务器的三种实现模型

    服务器设计技术有很多,按使用的协议来分有 TCP 服务器和 UDP 服务器,按处理方式来分有循环服务器和并发服务器. 循环服务器与并发服务器模型 在网络程序里面,一般来说都是许多客户对应一个服务器(多 ...

  7. linux网络编程之并发服务器的三种实现模型 (超级经典)

    转载 : http://blog.csdn.net/tennysonsky/article/details/45671215 服务器设计技术有很多,按使用的协议来分有 TCP 服务器和 UDP 服务器 ...

  8. 【Linux网络编程】并发服务器之select模型

    00. 目录 文章目录 00. 目录 01. 概述 02. I/O复用技术概述 03. select模型服务器实现思路 04. select模型服务器实现 05. 附录 01. 概述 服务器设计技术有 ...

  9. 【Linux网络编程】并发服务器之多线程模型

    00. 目录 文章目录 00. 目录 01. 概述 02. 多线程服务器 03. 多线程服务器实现思路 04. 多线程服务器实现 05. 附录 01. 概述 服务器设计技术有很多,按使用的协议来分有 ...

最新文章

  1. 借助Redis锁,完美解决高并发秒杀问题
  2. NYOJ 598 旋转圆柱矩阵
  3. gis影像格式img转为ecw_医学影像图片格式
  4. java 排列3_java中的三大排序算法
  5. netty心跳过程中 发送消息失败_Netty 4.0 实现心跳检测和断线重连
  6. 关于垂直切分Vertical Sharding的粒度
  7. hadoop面试题答案
  8. Kali Linux Web 渗透测试秘籍 第二章 侦查
  9. 底大一级压死人!华为Mate 30 Pro主摄CMOS或将达到1/1.5英寸
  10. 数组的方法之(Array.prototype.reduce() 方法)
  11. 山寨笔记本电脑风暴要来了
  12. sql server2016还原数据库
  13. 我们雇佣了一只大猴子
  14. 记一次隐藏动态库符号的探索过程
  15. 深圳市专利代理机构名单(截至2016年3月)
  16. egg项目和DVA项目的目录结构比较
  17. 霍营派出所办理居住证
  18. 大数据分析02——成都二手房(热度)
  19. c语言蒸汽流量温度压力补偿运算,当蒸汽流量测量使用温度压力补偿,这七点不容忽略!...
  20. 微信无法显示好友头像

热门文章

  1. 查找出系统中大于50k 且小于100k 的文件并删除。
  2. 进阶篇-用户界面:4.Android中常用组件
  3. centos6.5安装配置LDAP服务[转]
  4. hdu 1564 Play a game
  5. Could not load the assembly 'DotNetNuke.Authentication.LiveID'. Make sure that it is compiled before
  6. postgresql存图片字段类型_PostgreSQL让人着迷的多态性,另辟蹊径省时又省力
  7. android 坐标点计算器,Android实现简易计算器
  8. uniapp弹出框_uniApp上拉刷新,下拉加载,以及筛选功能
  9. linux制作一键恢复,Linux/Centos Mondo 一键部署、镜像恢复,快速部署
  10. 用python做数据分析流程图_使用Pyecharts进行高级数据可视化