1. #include <stdio.h>
    2. #include <sys/types.h>
    3. #include <sys/socket.h>
    4. #include <errno.h>
    5. #include <string.h>
    6. #include <stdlib.h>
    7. #include <unistd.h>
    8. #include <netinet/in.h>
    9. #include <ctype.h>
    10. #include <poll.h> //poll头文件
    11. #define MAXSIZE 1024
    12. #define IP_ADDR "127.0.0.1"
    13. #define IP_PORT 8888
    14. int main()
    15. {
    16. int i_listenfd, i_connfd;
    17. struct sockaddr_in st_sersock;
    18. char msg[MAXSIZE];
    19. int nrecvSize = 0;
    20. int index = 0; //记录fd数组中最大fd对应的下标
    21. struct pollfd pofds[MAXSIZE]; //结构体数组
    22. for (n : pofds) //将所有数组中的fd设为-1,方便以后填充
    23. {
    24. n.fd = -1;
    25. }
    26. if ((i_listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) //建立socket套接字
    27. {
    28. printf("socket Error: %s (errno: %d)\n", strerror(errno), errno);
    29. exit(0);
    30. }
    31. memset(&st_sersock, 0, sizeof(st_sersock));
    32. st_sersock.sin_family = AF_INET; //IPv4协议
    33. st_sersock.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY转换过来就是0.0.0.0,泛指本机的意思,也就是表示本机的所有IP,因为有些机子不止一块网卡,多网卡的情况下,这个就表示所有网卡ip地址的意思。
    34. st_sersock.sin_port = htons(IP_PORT);
    35. if (bind(i_listenfd, (struct sockaddr *)&st_sersock, sizeof(st_sersock)) < 0) //将套接字绑定IP和端口用于监听
    36. {
    37. printf("bind Error: %s (errno: %d)\n", strerror(errno), errno);
    38. exit(0);
    39. }
    40. if (listen(i_listenfd, 20) < 0) //设定可同时排队的客户端最大连接个数
    41. {
    42. printf("listen Error: %s (errno: %d)\n", strerror(errno), errno);
    43. exit(0);
    44. }
    45. printf("listen fd: %d\n", i_listenfd);
    46. pofds[index].fd = i_listenfd; //先赋值
    47. pofds[index].events = POLLIN;
    48. printf("======waiting for client's request======\n");
    49. //准备接受客户端连接
    50. while (1)
    51. {
    52. int nCount = poll(pofds, index + 1, -1); //阻塞监听
    53. printf("----------poll监听到可读事件计数:%d\n", nCount);
    54. for (int i = 0; i < MAXSIZE; i++)
    55. {
    56. if (nCount == 0)
    57. {
    58. break;
    59. }
    60. if (!(pofds[i].revents & POLLIN))
    61. {
    62. continue; //不在监听事件中则跳过
    63. }
    64. printf("----------即将处理监听到的 pofds[%d]: %d\n", i, pofds[i].fd);
    65. nCount--; //每处理一次就自减1
    66. if (pofds[i].fd == i_listenfd) //监听到有客户端连接
    67. {
    68. if ((i_connfd = accept(i_listenfd, (struct sockaddr *)NULL, NULL)) < 0) //阻塞等待客户端连接
    69. {
    70. printf("accept Error: %s (errno: %d)\n", strerror(errno), errno);
    71. // continue;
    72. }
    73. else
    74. {
    75. printf("Client[%d], welcome!\n", i_connfd);
    76. }
    77. for (int n = 0; n < MAXSIZE; n++)
    78. {
    79. if (pofds[n].fd == -1) //将新客户端fd加入数组中
    80. {
    81. pofds[n].fd = i_connfd;
    82. pofds[n].events = POLLIN;
    83. index < n ? index = n : true;
    84. printf("将新客户端fd加入数组中. fd:%d, index:%d\n", pofds[n].fd, index);
    85. break;
    86. }
    87. }
    88. }
    89. else //监听到已连接的客户端发来的数据
    90. {
    91. //接受客户端发来的消息并作处理(小写转大写)后回写给客户端
    92. memset(msg, 0, sizeof(msg));
    93. if ((nrecvSize = read(pofds[i].fd, msg, MAXSIZE)) < 0)
    94. {
    95. printf("accept Error: %s (errno: %d)\n", strerror(errno), errno);
    96. continue;
    97. }
    98. else if (nrecvSize == 0) //read返回0代表对方已close断开连接。
    99. {
    100. printf("client has disconnected!\n");
    101. if (index == i) //如果是最大的下标的客户端退出,则index-1
    102. {
    103. index--;
    104. }
    105. pofds[i].fd = -1; //清除数组中相应位置
    106. close(pofds[i].fd);
    107. continue;
    108. }
    109. else
    110. {
    111. printf("recvMsg:%s", msg);
    112. for (int i = 0; msg[i] != '\0'; i++)
    113. {
    114. msg[i] = toupper(msg[i]);
    115. }
    116. if (write(pofds[i].fd, msg, strlen(msg) + 1) < 0)
    117. {
    118. printf("accept Error: %s (errno: %d)\n", strerror(errno), errno);
    119. }
    120. }
    121. }
    122. }
    123. } //while
    124. close(i_listenfd);
    125. return 0;
    126. }