1. /* 实现功能:通过epoll, 处理多个socket
  2. * 监听一个端口,监听到有链接时,添加到epoll_event
  3. * xs
  4. */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <sys/socket.h>
  9. #include <poll.h>
  10. #include <sys/epoll.h>
  11. #include <sys/time.h>
  12. #include <netinet/in.h>
  13. #define MYPORT 12345
  14. //最多处理的connect
  15. #define MAX_EVENTS 500
  16. //当前的连接数
  17. int currentClient = 0;
  18. //数据接受 buf
  19. #define REVLEN 10
  20. char recvBuf[REVLEN];
  21. //epoll描述符
  22. int epollfd;
  23. //事件数组
  24. struct epoll_event eventList[MAX_EVENTS];
  25. void AcceptConn(int srvfd);
  26. void RecvData(int fd);
  27. int main()
  28. {
  29. int i, ret, sinSize;
  30. int recvLen = 0;
  31. fd_set readfds, writefds;
  32. int sockListen, sockSvr, sockMax;
  33. int timeout;
  34. struct sockaddr_in server_addr;
  35. struct sockaddr_in client_addr;
  36. //socket
  37. if((sockListen=socket(AF_INET, SOCK_STREAM, 0)) < 0)
  38. {
  39. printf("socket error\n");
  40. return -1;
  41. }
  42. bzero(&server_addr, sizeof(server_addr));
  43. server_addr.sin_family = AF_INET;
  44. server_addr.sin_port = htons(MYPORT);
  45. server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  46. //bind
  47. if(bind(sockListen, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
  48. {
  49. printf("bind error\n");
  50. return -1;
  51. }
  52. //listen
  53. if(listen(sockListen, 5) < 0)
  54. {
  55. printf("listen error\n");
  56. return -1;
  57. }
  58. // epoll 初始化
  59. epollfd = epoll_create(MAX_EVENTS);
  60. struct epoll_event event;
  61. event.events = EPOLLIN|EPOLLET;
  62. event.data.fd = sockListen;
  63. //add Event
  64. if(epoll_ctl(epollfd, EPOLL_CTL_ADD, sockListen, &event) < 0)
  65. {
  66. printf("epoll add fail : fd = %d\n", sockListen);
  67. return -1;
  68. }
  69. //epoll
  70. while(1)
  71. {
  72. timeout=3000;
  73. //epoll_wait
  74. int ret = epoll_wait(epollfd, eventList, MAX_EVENTS, timeout);
  75. if(ret < 0)
  76. {
  77. printf("epoll error\n");
  78. break;
  79. }
  80. else if(ret == 0)
  81. {
  82. printf("timeout ...\n");
  83. continue;
  84. }
  85. //直接获取了事件数量,给出了活动的流,这里是和poll区别的关键
  86. int i = 0;
  87. for(i=0; i<ret; i++)
  88. {
  89. //错误退出
  90. if ((eventList[i].events & EPOLLERR) ||
  91. (eventList[i].events & EPOLLHUP) ||
  92. !(eventList[i].events & EPOLLIN))
  93. {
  94. printf ( "epoll error\n");
  95. close (eventList[i].data.fd);
  96. return -1;
  97. }
  98. if (eventList[i].data.fd == sockListen)
  99. {
  100. AcceptConn(sockListen);
  101. }else{
  102. RecvData(eventList[i].data.fd);
  103. }
  104. }
  105. }
  106. close(epollfd);
  107. close(sockListen);
  108. return 0;
  109. }
  110. /**************************************************
  111. 函数名:AcceptConn
  112. 功能:接受客户端的链接
  113. 参数:srvfd:监听SOCKET
  114. ***************************************************/
  115. void AcceptConn(int srvfd)
  116. {
  117. struct sockaddr_in sin;
  118. socklen_t len = sizeof(struct sockaddr_in);
  119. bzero(&sin, len);
  120. int confd = accept(srvfd, (struct sockaddr*)&sin, &len);
  121. if (confd < 0)
  122. {
  123. printf("bad accept\n");
  124. return;
  125. }else
  126. {
  127. printf("Accept Connection: %d", confd);
  128. }
  129. //将新建立的连接添加到EPOLL的监听中
  130. struct epoll_event event;
  131. event.data.fd = confd;
  132. event.events = EPOLLIN|EPOLLET;
  133. epoll_ctl(epollfd, EPOLL_CTL_ADD, confd, &event);
  134. }
  135. //读取数据
  136. void RecvData(int fd)
  137. {
  138. int ret;
  139. int recvLen = 0;
  140. memset(recvBuf, 0, REVLEN);
  141. printf("RecvData function\n");
  142. if(recvLen != REVLEN)
  143. {
  144. while(1)
  145. {
  146. //recv数据
  147. ret = recv(fd, (char *)recvBuf+recvLen, REVLEN-recvLen, 0);
  148. if(ret == 0)
  149. {
  150. recvLen = 0;
  151. break;
  152. }
  153. else if(ret < 0)
  154. {
  155. recvLen = 0;
  156. break;
  157. }
  158. //数据接受正常
  159. recvLen = recvLen+ret;
  160. if(recvLen<REVLEN)
  161. {
  162. continue;
  163. }
  164. else
  165. {
  166. //数据接受完毕
  167. printf("buf = %s\n", recvBuf);
  168. recvLen = 0;
  169. break;
  170. }
  171. }
  172. }
  173. printf("data is %s", recvBuf);
  174. }

epoll+socket实现 socket并发 linux服务器的更多相关文章

  1. linux服务器最大连接数

    1 受内存限制 每个tcp连接是一个打开的socket文件,因此linux服务器的最大连接数受linux操作系统单个进程同时打开的最大文件数的限制. 这个限制本质上是对单个进程内存的限制. 查看进程最 ...

  2. Linux网络服务器epoll模型的socket通讯的实现(一)

    准备写一个网络游戏的服务器的通讯模块,参考网上看到的一些代码,在linux下面实现一个多线程的epoll模型的socket通讯的代码,以下是第一部分多线程的切换代码: 1 #include <s ...

  3. 网络编程socket 结合IO多路复用select; epool机制分别实现单线程并发TCP服务器

    select版-TCP服务器 1. select 原理 在多路复用的模型中,比较常用的有select模型和epoll模型.这两个都是系统接口,由操作系统提供.当然,Python的select模块进行了 ...

  4. 一小时学会用Python Socket 开发可并发的FTP服务器!!

    socket是什么 什么是socket所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络发出请求 ...

  5. socket编程之并发回射服务器

    使用到的函数: // 子进程返回0,父进程返回子进程ID,出错返回-1 pid_t fork(void); pid_t wait(int *wstatus); // 最常用的option是WNOHAN ...

  6. Linux Xshell连接Linux服务器时报错Socket error Event: 32 Error: 10053

    问题描述 在用Xshell连接Linux服务器时,出现错误提示"Socket error Event: 32 Error: 10053. Connection closing...Socke ...

  7. socket编程之并发回射服务器3

    在socket编程之并发回射服务器一文中,服务器采用多进程的方式实现并发,本文采用多线程的方式实现并发. 多线程相关API: // Compile and link with -pthread int ...

  8. socket编程之并发回射服务器2

    承接上文:socket编程之并发回射服务器 为了让服务器进程的终止一经发生,客户端就能检测到,客户端需要能够同时处理两个描述符:套接字和用户输入. 可以使用select达到这一目的: void str ...

  9. Linux服务器高并发实践经历

    作为一个师父离职早的野生程序员,业务方面还可以达到忽悠别人的水平,但上升到性能层面那就是硬伤. 真实天上掉馅饼,公司分配了一个测试性能的任务,真是感觉我的天空星星都亮了. 高并发主要限制因素:CPU. ...

随机推荐

  1. 华为交换机VRP系统命令试图

  2. XFS文件系统的备份和恢复

    1.工具 XFS文件系统提供了xfsdump和xfsrestore来协助备份.恢复XFS文件系统中的数据,xfsdump按inode顺序来备份XFS文件系统,备份时不需要卸载文件系统,备份和恢复的过程 ...

  3. XCube和X组件的入门级使用教程

    我也是一个入门级的初学者,在学习魔方的时候,很多不是很懂的地方,而网上的资料又比较少.尤其是Newlife的论坛打不开的情况下 所以就想着把这个初级项目做完后,做一个入门级教程.保证人人都看得懂(.^ ...

  4. jqGrid选择列控件向右拖拽超出边界处理

    jqGrid选择列控件向右拖拽超出边界处理 $("#tb_DeviceInfo").jqGrid('navButtonAdd', '#jqGridPager', {         ...

  5. react 的基础

    首先下载React 的安装包,可以到官网下载.也可以使用React Demos 已经自带 React 源码,不用另外安装,只需把这个库拷贝到硬盘中使用. (可参考http://www.ruanyife ...

  6. jdbc模板

    public class JdbcTest { public static void main(String[] args) { //数据库连接 Connection connection = nul ...

  7. Python爬虫入门之正则表达式

    在前面我们已经搞定了怎样获取页面的内容,不过还差一步,这么多杂乱的代码夹杂文字我们怎样把它提取出来整理呢?下面就开始介绍一个十分强大的工具,正则表达式! 1.了解正则表达式 正则表达式是对字符串操作的 ...

  8. 【Alpha】项目展示

    团队成员介绍 大娃 后端开发人员,主要工作为后端开发,文档撰写. 大娃的个人博客 二娃 PM,主要工作为项目进度把控,平日例会的记录,例会博客及部分其他博客的撰写. 二娃的个人博客 三娃 PM,主要工 ...

  9. linux安装anaconda3 conda: command not found

    在使用Anaconda3时出现: conda:未找到命令 最后发现每次开机后都要运行一个命令才行:export PATH=~/anaconda3/bin:$PATH 如果要永久保存路径: 1.在终端输 ...

  10. Java代码调用服务器上的Shell脚本

    Java代码调用服务器上的Shell脚本 这里主要是因为我们报表平台有用到用户手工录入的数据作为结果数据且需要纳入saiku去展示 如我们所知,saiku不会自动刷新,所以需要在数据更新接口中调用服务 ...