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. 【网络编程】非阻塞connect详解
  2. smc数显压力表设定方法_SMC压力表使用注意与调试方法
  3. java 的序列化和反序列化的问题
  4. 人脸识别入侵生活,但“刷脸”背后你的信息安全吗?
  5. Maven类包冲突终极解决小技若干
  6. MyBatis 实际使用案例-settings
  7. C或C 如何通过程序执行shell命令并获取命令执行结果?
  8. Bootstrap3.0入门学习系列规划[持续更新]
  9. cssz中a标签鼠标选中去除选中边框
  10. maven笔记(2)-- 构建Java Project 及 Maven命令使用
  11. guava 工具类及代码
  12. 极其艰难地下了决心建立博客虽然没有很好的理由或者仅仅是因为觉得自己的确要改变了......
  13. 计算机机设应用基础,计算机机应用基础–word.ppt
  14. iOS 生成证书、描述文件、打包上架Appstore详细流程
  15. linux 上supervisor的进程管理工具的使用
  16. Java 中Calendar的使用
  17. Ubuntu关于串口的操作(查看串口信息、串口助手、串口权限)
  18. 红心大战c语言程序设计,Win 7系统安全优化、瘦身攻略(2)
  19. Python面向对象实现栈和图书管理系统
  20. 卸载高版本的labview的vision模块和VAS采集模块装低版本

热门文章

  1. intellij idea中解决java.lang.VerifyError: Expecting a stackmap frame at branch target的方法
  2. Android JNI编程(五)——C语言的静态内存分配、动态内存分配、动态创建数组...
  3. python学习笔记四——数据类型
  4. JSON学习资料整理
  5. BCD码与十进制的相互转换
  6. mvc的Controller返回值类型ActionResult详解
  7. 对多个WCF服务进行统一的连接测试
  8. HTML浮动导致高度塌陷,HTML 文档流,设置元素浮动,导致父元素高度无法自适应的解决方法(高度欺骗)...
  9. java数组交集_java数组的交集和并集
  10. 图灵机器人调用数据恢复_机器人也能撩妹?python程序员自制微信机器人,替他俘获女神芳心...