1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
#define MAXCONN 5 //连接队列中的个数 int main() { int fd[MAXCONN]={0}; //连接的fd int conn_amount; //当前的连接数 int sock_fd,new_fd; //监听套接字 连接套接字 fd_set fdsr; //文件描述符集的定义 int maxsock; struct timeval tv; struct sockaddr_in server_addr; // 服务器的地址信息 struct sockaddr_in client_addr; //客户端的地址信息 socklen_t sin_size; int ret,i; char buf[256]={0}; memset(&server_addr,0,sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(9999); server_addr.sin_addr.s_addr = INADDR_ANY;//通配IP //建立sock_fd套接字 if((sock_fd = socket(AF_INET,SOCK_STREAM,0))==-1) { perror("setsockopt"); exit(1); } if(bind(sock_fd,(struct sockaddr *)&server_addr,sizeof(server_addr)) == -1) { perror("bind error!n"); exit(1); } if(listen(sock_fd,MAXCONN)==-1) { perror("listen error!n"); exit(1); } printf("listen port 9999n"); conn_amount =0; sin_size = sizeof(client_addr); maxsock = sock_fd; while(1) { //初始化文件描述符集合 FD_ZERO(&fdsr); //清除描述符集 FD_SET(sock_fd,&fdsr); //把sock_fd加入描述符集 //超时的设定 tv.tv_sec = 30; tv.tv_usec =0; //添加活动的连接 for(i=0;i<MAXCONN;i++) { if(fd[i]!=0) { FD_SET(fd[i],&fdsr); } } //如果文件描述符中有连接请求会做相应的处理,实现I/O的复用 多用户的连接通讯 ret = select(maxsock +1,&fdsr,NULL,NULL,&tv); if(ret < 0) //没有找到有效的连接 失败 { perror("select error!n"); break; } else if(ret == 0)// 指定的时间到, { printf("timeout n"); continue; } //循环判断有效的连接是否有数据到达 for(i=0;i<conn_amount;i++) { if(FD_ISSET(fd[i],&fdsr)) { memset(buf,0,256); ret = recv(fd[i],buf,sizeof(buf),0); if(ret <=0) //客户端连接关闭,清除文件描述符集中的相应的位 { printf("client[%d] closen",i); close(fd[i]); FD_CLR(fd[i],&fdsr); fd[i]=0; conn_amount--; } else//否则有相应的数据发送过来 ,进行相应的处理 { //buf[ret]=0; printf("%dn",ret); printf("client[%d] send:%sn",i,buf); send(fd[i],buf,sizeof(buf),0); } } }//for if(FD_ISSET(sock_fd,&fdsr)) { new_fd = accept(sock_fd,(struct sockaddr *)&client_addr,&sin_size); if(new_fd <=0) { perror("accept errorn"); continue; } //添加新的fd 到数组中 判断有效的连接数是否小于最大的连接数,如果小于的话,就把新的连接套接字加入集合 if(conn_amount <MAXCONN) { for(i=0;i< MAXCONN;i++) { if(fd[i]==0) { fd[i] = new_fd; break; } } conn_amount++; printf("new connection client[%d] %s:%dn",conn_amount,inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port)); if(new_fd > maxsock) { maxsock = new_fd; } } else { printf("max connections arrive ,exitn"); send(new_fd,"bye",4,0); close(new_fd); continue; } } }//while for(i=0;i<MAXCONN;i++) { if(fd[i]!=0) { close(fd[i]); } } exit(0); } |
转载请注明:爱开源 » 有用的代码小片段2-TCP,Socket,Select