/* 采用链表来保存【连接socket】 */#include "wrap.h"#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <errno.h>#include <sys/socket.h> #include <arpa/inet.h>#include <ctype.h>#include <strings.h>#define SRV_PORT 2222#define LISTEN_BACKLOG 128#define CLIENT_MAXSIZE 1024struct cfd_node{ uint connfd; struct cfd_node* next;};struct cfd_node* head=NULL;int main(int argc,char* argv[]){ uint lfd,cfd,max_fd; struct cfd_node* ptr,*preptr; char buf[BUFSIZ]; struct sockaddr_in srv_addr,client_addr; socklen_t client_addr_len,srv_addr_len; char client_ip_addr[20]; lfd=Socket(AF_INET,SOCK_STREAM,0); max_fd=lfd; srv_addr_len=sizeof(srv_addr); init_sockaddr_in((struct sockaddr*)&srv_addr,srv_addr_len,AF_INET,SRV_PORT,INADDR_ANY); Bind(lfd,(struct sockaddr*)&srv_addr,srv_addr_len); int opt=1; setsockopt(lfd,SOL_SOCKET,SO_REUSEPORT,&opt,sizeof(opt)); /* 多路复用 */ Listen(lfd,LISTEN_BACKLOG); fd_set rset,allset; /* 读集合,备份集合 */ FD_ZERO(&allset); FD_SET(lfd,&allset); while(1){ rset=allset; int sel_ret=Select(max_fd+1,&rset,NULL,NULL,NULL); printf("Listen success! current fd num:%d\n",sel_ret); if(sel_ret>0){ if(FD_ISSET(lfd,&rset)){ client_addr_len=sizeof(client_addr); cfd=Accept(lfd,(struct sockaddr*)&client_addr,&client_addr_len); FD_SET(cfd,&allset); /* 头插法 */ struct cfd_node* node=malloc(sizeof(struct cfd_node)); node->connfd=cfd; node->next=head; head=node; printf("new client coming! ip: %s port %d \n", inet_ntop(AF_INET,&client_addr.sin_addr.s_addr,client_ip_addr,sizeof(client_ip_addr)) ,ntohs(client_addr.sin_port)); max_fd=(cfd>max_fd?cfd:max_fd); if(sel_ret==1) continue; }#ifdef SIMPLE /* 数据处理-轮询 */ for(int connfd=lfd+1;connfd<max_fd+1;connfd++){ printf("work!\t"); if(FD_ISSET(connfd,&rset)){ int n=Read(connfd,buf,sizeof(buf)); if( n == 0){ printf("connect close!\n"); Close(connfd); FD_CLR(connfd,&allset); }else if(n>0){ printf("%d bytes data coming!\n",n); Write(STDOUT_FILENO,buf,n); for(int j=0;j<n;j++){ buf[j]=toupper(buf[j]); } Write(connfd,buf,n); } } }#else /* 链表轮询 */ ptr=head; preptr=NULL; while(ptr!=NULL){ int connfd=ptr->connfd; if(FD_ISSET(connfd,&rset)){ int n=Read(connfd,buf,sizeof(buf)); if( n == 0){ printf("connect close!\n"); Close(connfd); FD_CLR(connfd,&allset); /* 链表中删除失效socket */ if(preptr==NULL){//头结点 head=ptr->next; } else if(ptr->next!=NULL){ preptr->next=ptr->next; } free(ptr); }else if(n>0){ Write(STDOUT_FILENO,buf,n); for(int j=0;j<n;j++){ buf[j]=toupper(buf[j]); } Write(connfd,buf,n); } } preptr=ptr; ptr=ptr->next; }#endif } } return 0;}