转载:http://blog.csdn.net/szkbsgy/article/details/10558881

[cpp] view plaincopy
  1. <span style="font-size:18px;">服务端:
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <sys/time.h>
  6. #include <sys/types.h>
  7. #include <sys/socket.h>
  8. #include <netinet/in.h>
  9. #include <sys/select.h>
  10. #include <errno.h>
  11. #define SERVER_IP "127.0.0.1"
  12. #define SERVER_PORT 8000
  13. #define MAX_RECV_LEN 1024
  14. #define MAX_CLIENT_NUM 30
  15. #define BACK_LOG 20
  16. static int running = 1;
  17. int main(int argc, char *argv[])
  18. {
  19. int sock_fd = -1;
  20. int ret = -1;
  21. struct sockaddr_in serv_addr;
  22. struct sockaddr_in cli_addr;
  23. socklen_t serv_addr_len = 0;
  24. socklen_t cli_addr_len = 0;
  25. int client_fd[MAX_CLIENT_NUM];
  26. char recv_buf[MAX_RECV_LEN];
  27. int new_conn_fd = -1;
  28. int i = 0;
  29. int max_fd = -1;
  30. int num = -1;
  31. struct timeval timeout;
  32. fd_set read_set;
  33. fd_set write_set;
  34. fd_set select_read_set;
  35. FD_ZERO(&read_set);
  36. FD_ZERO(&write_set);
  37. FD_ZERO(&select_read_set);
  38. for (i = 0; i < MAX_CLIENT_NUM; i++)
  39. {
  40. client_fd[i] = -1;
  41. }
  42. memset(&serv_addr, 0, sizeof(serv_addr));
  43. memset(&cli_addr, 0, sizeof(cli_addr));
  44. sock_fd = socket(AF_INET, SOCK_STREAM, 0);
  45. if (sock_fd < 0)
  46. {
  47. perror("Fail to socket");
  48. exit(1);
  49. }
  50. serv_addr.sin_family = AF_INET;
  51. serv_addr.sin_port = htons(SERVER_PORT);
  52. serv_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
  53. unsigned int value = 1;
  54. if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR,
  55. (void *)&value, sizeof(value)) < 0)
  56. {
  57. perror("Fail to setsockopt");
  58. exit(1);
  59. }
  60. serv_addr_len = sizeof(serv_addr);
  61. if (bind(sock_fd, (struct sockaddr*)&serv_addr, serv_addr_len) < 0)
  62. {
  63. perror("Fail to bind");
  64. exit(1);
  65. }
  66. if (listen(sock_fd, BACK_LOG) < 0)
  67. {
  68. perror("Fail to listen");
  69. exit(1);
  70. }
  71. char buf[1024];
  72. max_fd = sock_fd;
  73. int len;
  74. FD_SET(sock_fd, &read_set);
  75. while (running)
  76. {
  77. timeout.tv_sec = 5;
  78. timeout.tv_usec = 0;
  79. max_fd = sock_fd;
  80. for (i = 0; i < MAX_CLIENT_NUM; i++)
  81. {
  82. if (max_fd < client_fd[i])
  83. {
  84. max_fd = client_fd[i];
  85. }
  86. }
  87. select_read_set = read_set;
  88. ret = select(max_fd + 1, &select_read_set, NULL, NULL, &timeout);
  89. if (ret == 0)
  90. {
  91. printf("timeout\n");
  92. }
  93. else if (ret < 0)
  94. {
  95. printf("error occur\n");
  96. }
  97. else
  98. {
  99. if (FD_ISSET(sock_fd, &select_read_set))
  100. {
  101. printf("new client comes\n");
  102. len = sizeof(cli_addr);
  103. new_conn_fd = accept(sock_fd, (struct sockaddr*)&cli_addr, &len);
  104. if (new_conn_fd < 0)
  105. {
  106. perror("Fail to accept");
  107. exit(1);
  108. }
  109. else
  110. {
  111. for (i = 0; i < MAX_CLIENT_NUM; i++)
  112. {
  113. if (client_fd[i] == -1)
  114. {
  115. client_fd[i] = new_conn_fd;
  116. FD_SET(new_conn_fd, &read_set);
  117. break;
  118. }
  119. if (max_fd < new_conn_fd)
  120. {
  121. max_fd = new_conn_fd;
  122. }
  123. }
  124. }
  125. }
  126. else
  127. {
  128. for (i = 0; i < MAX_CLIENT_NUM; i++)
  129. {
  130. if (-1 == client_fd[i]) {
  131. continue;
  132. }
  133. memset(recv_buf, 0, MAX_RECV_LEN);
  134. if (FD_ISSET(client_fd[i], &select_read_set))
  135. {
  136. num = read(client_fd[i], recv_buf, MAX_RECV_LEN);
  137. if (num < 0)
  138. {
  139. printf("Client(%d) left\n", client_fd[i]);
  140. FD_CLR(client_fd[i], &read_set);
  141. close(client_fd[i]);
  142. client_fd[i] = -1;
  143. }
  144. else if (num > 0)
  145. {
  146. recv_buf[num] = '\0';
  147. printf("Recieve client(%d) data\n", client_fd[i]);
  148. printf("Data: %s\n\n", recv_buf);
  149. } if (num == 0)
  150. {
  151. printf("Client(%d) exit\n", client_fd[i]);
  152. FD_CLR(client_fd[i], &read_set);
  153. close(client_fd[i]);
  154. client_fd[i] = -1;
  155. }
  156. }
  157. }
  158. }
  159. }
  160. }
  161. return 0;
  162. }
  163. 客户端:
  164. #include <stdio.h>
  165. #include <stdlib.h>
  166. #include <string.h>
  167. #include <unistd.h>
  168. #include <sys/time.h>
  169. #include <sys/types.h>
  170. #include <sys/socket.h>
  171. #include <netinet/in.h>
  172. #include <sys/select.h>
  173. #define SERVER_IP "127.0.0.1"
  174. #define SERVER_PORT 8000
  175. #define MAX_RECV_LEN 1024
  176. static int running = 1;
  177. int main(int argc, char *argv[])
  178. {
  179. int sock_fd = -1;
  180. int ret = -1;
  181. struct sockaddr_in serv_addr;
  182. struct sockaddr_in cli_addr;
  183. socklen_t serv_addr_len = 0;
  184. memset(&serv_addr, 0, sizeof(serv_addr));
  185. sock_fd = socket(AF_INET, SOCK_STREAM, 0);
  186. if (sock_fd < 0)
  187. {
  188. perror("Fail to socket");
  189. exit(1);
  190. }
  191. serv_addr.sin_family = AF_INET;
  192. serv_addr.sin_port = htons(SERVER_PORT);
  193. serv_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
  194. serv_addr_len = sizeof(serv_addr);
  195. if (connect(sock_fd, (struct sockaddr *)&serv_addr, serv_addr_len) < 0)
  196. {
  197. perror("Fail to connect");
  198. exit(1);
  199. }
  200. char buf[1024];
  201. int num = 0;
  202. while (running)
  203. {
  204. num = read(STDIN_FILENO, buf, MAX_RECV_LEN);
  205. if (num > 0)
  206. {
  207. buf[num] = '\0';
  208. printf("buf: %s\n", buf);
  209. num = write(sock_fd, buf, num);
  210. if (num < 0)
  211. {
  212. printf("write failed\n");
  213. exit(1);
  214. }
  215. if (strncmp(buf, "exit", strlen("exit")) == 0)
  216. {
  217. printf("Client exit\n");
  218. close(sock_fd);
  219. return 0;
  220. }
  221. }
  222. }
  223. return 0;
  224. } </span>
0

Linux select 实现并发服务器和客户端相关推荐

  1. Linux select TCP并发服务器与客户端编程

    介绍:运行在ubuntu linux系统,需要先打开一个终端运行服务端代码,这时,可以打开多个终端同时运行多个客户端代码(注意客户端数目要小于MAX_FD);在客户端输入数据后回车,可以看见服务器收到 ...

  2. 1 linux下tcp并发服务器的几种设计的模式套路,Linux下几种并发服务器的实现模式(详解)...

    1>单线程或者单进程 相当于短链接,当accept之后,就开始数据的接收和数据的发送,不接受新的连接,即一个server,一个client 不存在并发. 2>循环服务器和并发服务器 1.循 ...

  3. Linux 网络编程——并发服务器的三种实现模型

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

  4. alma linux 上配置 ntp 服务器和客户端

    目录 配置 NTP 服务器 1.Chrony 是默认的 NTP 客户端以及RHEL和 AlmaLinux 上的 NTP 服务器 2.使 chrony 服务在系统启动时自动启动 3.由于 chrony ...

  5. go语言实现tcp并发服务器与客户端

    go语言实现tcp并发服务器端与客户端 server.go // nc 连接, 发送字母, 加收到转大写的字母 // 如果发送exit ,则会断开连接 package mainimport (&quo ...

  6. epoll ET模式服务器和客户端源码例子

    关于epoll替代select作为高性能服务器的事件通知机制的资料相当多,我就不在这里班门弄斧了,有兴趣的同学可以参考末尾的文献链接. 这里说明如下: 1.epoll是linux下高并发服务器的完美方 ...

  7. 网络编程实战之高级篇, 彻底解决面试C10k问题, 高并发服务器, IO多路复用, 同时监视多个IO事件

    目录 一.前言 二.IO多路复用的理解 三.IO多路复用的发展 select poll epoll ​四.C10K服务端代码 五. 总结 一.前言 网络入门篇,从操作系统的层次推开网络大门 网络入门基 ...

  8. linux多进程网络实例,Linux下一个单进程并发服务器的实例 使用select

    /*单进程并发服务器实例.该程序采用单进程并发服务器算法实现的.*/ #include #include #include #include #include #include #include #i ...

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

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

最新文章

  1. html 文本框 无法输入,无法在HTML文本框中输入任何东西
  2. XCTF-MISC-新手区-gif
  3. 强悍的命令行 —— echo、env($PATH)、sudo
  4. Ionic开发App中重要的部分
  5. 5.hbase表新增数据同步之add_peer
  6. 导入导出mysql数据库
  7. 中美线径对照表_美标线径与国标对照及导线介绍
  8. SkeyePlayer RTSP/RTMP低延迟播放器源码解析系列之效率优化方案
  9. 使用Python的pandas库操作Excel
  10. 地球经纬度转换为unity球面坐标
  11. K8S从入门到放弃系列-(14)Kubernetes集群Dashboard部署
  12. 1:0 本立而道生!
  13. Python打印简单杨辉三角形
  14. 完美删除Mac Os自带输入法
  15. Linux下挂载NTFS分区
  16. 图片加水印的简单方法
  17. 计算机网络:从物理层到应用层的五层模型
  18. @Cacheable和@CachePut区别
  19. C#控件之Windows Media Player简单加载视频播放
  20. 【R语言】ggplot2---散点图的边框和颜色填充问题

热门文章

  1. node源码详解(五)
  2. Hibernate 基础配置及常用功能(二)
  3. 32位系统win2008+mssql2008 6G内存折腾纪实
  4. 判断滚动条是否到达页面的尾部
  5. 谈谈C#的私有成员的一个有趣的现象!
  6. EMF的一些总结(2)——关于EMF的序列化
  7. python后台开发知识点_面试总结:鹅厂Linux后台开发面试笔试C++知识点参考笔记...
  8. 一年中所有节日的排列顺序_计数问题(二)-排列组合的使用
  9. php put 参数,php – 如何在Guzzle 5中发送PUT请求的参数?
  10. Java是先难后易吗_在解决问题的时候,是先难后易还是先易后难?