1. /* 采用链表来保存【连接socket】 */
    2. #include "wrap.h"
    3. #include <stdlib.h>
    4. #include <stdio.h>
    5. #include <unistd.h>
    6. #include <errno.h>
    7. #include <sys/socket.h>
    8. #include <arpa/inet.h>
    9. #include <ctype.h>
    10. #include <strings.h>
    11. #define SRV_PORT 2222
    12. #define LISTEN_BACKLOG 128
    13. #define CLIENT_MAXSIZE 1024
    14. struct cfd_node{
    15. uint connfd;
    16. struct cfd_node* next;
    17. };
    18. struct cfd_node* head=NULL;
    19. int main(int argc,char* argv[]){
    20. uint lfd,cfd,max_fd;
    21. struct cfd_node* ptr,*preptr;
    22. char buf[BUFSIZ];
    23. struct sockaddr_in srv_addr,client_addr;
    24. socklen_t client_addr_len,srv_addr_len;
    25. char client_ip_addr[20];
    26. lfd=Socket(AF_INET,SOCK_STREAM,0);
    27. max_fd=lfd;
    28. srv_addr_len=sizeof(srv_addr);
    29. init_sockaddr_in((struct sockaddr*)&srv_addr,srv_addr_len,AF_INET,SRV_PORT,INADDR_ANY);
    30. Bind(lfd,(struct sockaddr*)&srv_addr,srv_addr_len);
    31. int opt=1;
    32. setsockopt(lfd,SOL_SOCKET,SO_REUSEPORT,&opt,sizeof(opt)); /* 多路复用 */
    33. Listen(lfd,LISTEN_BACKLOG);
    34. fd_set rset,allset; /* 读集合,备份集合 */
    35. FD_ZERO(&allset);
    36. FD_SET(lfd,&allset);
    37. while(1){
    38. rset=allset;
    39. int sel_ret=Select(max_fd+1,&rset,NULL,NULL,NULL);
    40. printf("Listen success! current fd num:%d\n",sel_ret);
    41. if(sel_ret>0){
    42. if(FD_ISSET(lfd,&rset)){
    43. client_addr_len=sizeof(client_addr);
    44. cfd=Accept(lfd,(struct sockaddr*)&client_addr,&client_addr_len);
    45. FD_SET(cfd,&allset);
    46. /* 头插法 */
    47. struct cfd_node* node=malloc(sizeof(struct cfd_node));
    48. node->connfd=cfd;
    49. node->next=head;
    50. head=node;
    51. printf("new client coming! ip: %s port %d \n",
    52. inet_ntop(AF_INET,&client_addr.sin_addr.s_addr,client_ip_addr,sizeof(client_ip_addr))
    53. ,ntohs(client_addr.sin_port));
    54. max_fd=(cfd>max_fd?cfd:max_fd);
    55. if(sel_ret==1) continue;
    56. }
    57. #ifdef SIMPLE
    58. /* 数据处理-轮询 */
    59. for(int connfd=lfd+1;connfd<max_fd+1;connfd++){
    60. printf("work!\t");
    61. if(FD_ISSET(connfd,&rset)){
    62. int n=Read(connfd,buf,sizeof(buf));
    63. if( n == 0){
    64. printf("connect close!\n");
    65. Close(connfd);
    66. FD_CLR(connfd,&allset);
    67. }else if(n>0){
    68. printf("%d bytes data coming!\n",n);
    69. Write(STDOUT_FILENO,buf,n);
    70. for(int j=0;j<n;j++){
    71. buf[j]=toupper(buf[j]);
    72. }
    73. Write(connfd,buf,n);
    74. }
    75. }
    76. }
    77. #else
    78. /* 链表轮询 */
    79. ptr=head;
    80. preptr=NULL;
    81. while(ptr!=NULL){
    82. int connfd=ptr->connfd;
    83. if(FD_ISSET(connfd,&rset)){
    84. int n=Read(connfd,buf,sizeof(buf));
    85. if( n == 0){
    86. printf("connect close!\n");
    87. Close(connfd);
    88. FD_CLR(connfd,&allset);
    89. /* 链表中删除失效socket */
    90. if(preptr==NULL){//头结点
    91. head=ptr->next;
    92. }
    93. else if(ptr->next!=NULL){
    94. preptr->next=ptr->next;
    95. }
    96. free(ptr);
    97. }else if(n>0){
    98. Write(STDOUT_FILENO,buf,n);
    99. for(int j=0;j<n;j++){
    100. buf[j]=toupper(buf[j]);
    101. }
    102. Write(connfd,buf,n);
    103. }
    104. }
    105. preptr=ptr;
    106. ptr=ptr->next;
    107. }
    108. #endif
    109. }
    110. }
    111. return 0;
    112. }