select_多路复用
1.头文件
1 #pragma once 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <sys/types.h> 6 #include <sys/select.h> 7 #include <sys/time.h> 8 #include <sys/socket.h> 9 #include <strings.h> 10 #include <string.h> 11 #include <arpa/inet.h> 12 13 #define IP "192.168.2.150" 14 #define PORT 9999 15 #define SIZE 128
2.client_select
1 #include "net.h" 2 3 int main(void) 4 { 5 //1.创建套接字 6 int fd = socket(AF_INET,SOCK_STREAM,0); 7 if(fd<0){ 8 perror("socket failed"); 9 exit(1); 10 } 11 12 13 //2.初始服务器地址 14 struct sockaddr_in cli; 15 cli.sin_family = AF_INET; 16 cli.sin_port = htons(PORT); 17 cli.sin_addr.s_addr=inet_addr(IP); 18 19 20 //3.发起连接请求 21 if( connect(fd,(struct sockaddr*)&cli,sizeof(cli))<0 ){ 22 perror("connect failed"); 23 exit(1); 24 } 25 26 27 //4.写 28 char buf[SIZE]; 29 while(1){ 30 bzero(buf,SIZE); 31 printf("please input: "); 32 fgets(buf,SIZE,stdin); 33 write(fd,buf,strlen(buf)); 34 if(!strncmp(buf,"quit",4)) 35 break; 36 } 37 38 39 //5.关闭 40 close(fd); 41 42 43 return 0 ; 44 }
3.server_select
1 #include "net.h" 2 3 int main(void) 4 { 5 char buf[SIZE]; 6 int newfd = -1; 7 8 //1.创建套接字 9 int fd = socket(AF_INET,SOCK_STREAM,0); 10 if(fd<0){ 11 perror("socket failed"); 12 exit(1); 13 } 14 15 16 //2.初始本地地址 17 struct sockaddr_in ser; 18 ser.sin_family = AF_INET; 19 ser.sin_port = htons(PORT); 20 ser.sin_addr.s_addr=htonl(INADDR_ANY); 21 22 23 //3.绑定 24 if( bind(fd,(struct sockaddr*)&ser,sizeof(ser))<0 ){ 25 perror("bind failed"); 26 exit(1); 27 } 28 29 //4.监听 30 if( listen(fd,5)<0 ){ 31 perror("listen failed"); 32 exit(1); 33 } 34 35 int len = sizeof(ser); 36 37 38 //5.多路复用 39 fd_set read_fds; //定义读集合 40 FD_ZERO(&read_fds); //清空读集合 41 int maxfd = fd; //最大描述符 42 43 44 //6.加入监听处理 读集合 45 while(1){ 46 FD_SET(0,&read_fds); //将标准输入加入读集合 47 FD_SET(fd,&read_fds); //将fd加入读集合 48 maxfd = fd; //表示最大读集合 49 if(maxfd < newfd){ 50 FD_SET(newfd,&read_fds); 51 maxfd = newfd; 52 } 53 54 int ret = select(maxfd+1,&read_fds,NULL,NULL,NULL); 55 if(ret<0){ 56 perror("select failed"); 57 exit(1); 58 } 59 else if(ret==0){ 60 perror("time out"); 61 break; 62 } 63 else{ 64 //6.1 判断输入端是否有相应 65 if(FD_ISSET(0,&read_fds)){ 66 bzero(buf,SIZE); 67 fgets(buf,SIZE,stdin); 68 printf("shell :%s",buf); 69 } 70 //6.2判断客户端是否有相应 71 if(FD_ISSET(fd,&read_fds)){ 72 //接收 73 newfd=accept(fd,(struct sockaddr*)&ser,&len); 74 if(newfd<0){ 75 perror("accept failed"); 76 exit(1); 77 } 78 printf("client connect succsee : ip=%s port=%d 用户上线啦 ^.^ ... ",inet_ntoa(ser.sin_addr),ntohs(ser.sin_port)); 79 } 80 //6.3判断客户端是否有数据 81 if(FD_ISSET(newfd,&read_fds)){ 82 bzero(buf,SIZE); // 读之前清理一下,要不然内存可能有残余保留!! 83 int val=read(newfd,buf,SIZE); 84 if(val<0){ 85 perror("read failed"); 86 exit(1); 87 } 88 else if(val==0){ 89 FD_CLR(newfd,&read_fds); 90 close(newfd); 91 newfd=-1; 92 } 93 else{ 94 printf("client info : ip=%s port=%d data=%s ",inet_ntoa(ser.sin_addr),ntohs(ser.sin_port),buf); 95 if(!strncmp(buf,"quit",4)) 96 printf("client info : ip=%s port=%d 用户下线啦 ^.^ ... ",inet_ntoa(ser.sin_addr),ntohs(ser.sin_port)); 97 } 98 } 99 } 100 } 101 102 103 return 0 ; 104 }
测试:
success !