套接字编程
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<sys/socket.h> 2 #include<sys/types.h> 3 #include<stdio.h> 4 #include<netinet/in.h> 5 #include<arpa/inet.h> 6 #include<errno.h> 7 #include<string.h> 8 #include<stdlib.h> 9 #include<unistd.h> 10 #include <sys/time.h> 11 #include <sys/types.h> 12 #include <unistd.h> 13 int main(int argc,char ** argv) 14 { 15 int listenfd; 16 17 listenfd=socket(AF_INET,SOCK_STREAM,0); 18 struct sockaddr_in myaddr; 19 myaddr.sin_family=AF_INET; 20 myaddr.sin_port=htons(atoi(argv[1])); 21 inet_pton(AF_INET,"192.168.6.11",&myaddr.sin_addr.s_addr); 22 23 int ret=bind(listenfd,(struct sockaddr *)&myaddr,sizeof(myaddr)); 24 if(ret<0) 25 { 26 perror("bind failed:"); 27 exit(0); 28 } 29 ret=listen(listenfd,20); 30 if(ret<0) 31 { 32 perror("listen failed:"); 33 exit(0); 34 } 35 struct sockaddr_in caddr; 36 int len=sizeof(caddr); 37 int confd; 38 char buf[100]; 39 40 fd_set set,rset;//定义一个文件描述符集合 41 FD_ZERO(&set);//清空文件描述符集合 42 FD_SET(listenfd,&set);//将文件描述符添加到集合里面去 43 44 int maxfd=listenfd; 45 /* 46 int select(int nfds, fd_set *readfds, fd_set *writefds, 47 fd_set *exceptfds, struct timeval *timeout); 48 49 第一个参数:是你要监听的最大文件描述符+1 50 返回值:如果有事件产生,返回的事件的个数.如果返回值为0,表示超时等待,出错返回负数 51 */ 52 53 int nfound; 54 while(1) 55 { 56 rset=set; 57 nfound=select(maxfd+1,&rset,NULL,NULL,NULL); 58 printf("nfound=%d\n",nfound); 59 if(nfound<0) 60 { 61 perror("select error"); 62 continue; 63 } 64 else if(nfound==0) 65 { 66 printf("超时等待..\n"); 67 continue; 68 } 69 if(FD_ISSET(listenfd,&rset))//FD_ISSET 判断文件描述符是否有事件产生,有返回真,没有返回假 70 { 71 printf("accept\n"); 72 confd=accept(listenfd,(struct sockaddr*)&caddr,&len); 73 if(confd<0) 74 { 75 perror("accept failed:"); 76 continue; 77 } 78 FD_SET(confd,&set); 79 if(confd>maxfd) 80 maxfd=confd; 81 FD_CLR(listenfd,&rset);//将监听的文件描述符集合中移除. 82 } 83 for(int fd=0;fd<=maxfd;fd++) 84 { 85 if(fd==listenfd) 86 continue; 87 if(!FD_ISSET(fd,&rset)) 88 continue; 89 ret=read(fd,buf,100); 90 if(ret<0) 91 { 92 FD_CLR(fd,&set);//将监听的文件描述符集合中移除. 93 close(fd); 94 perror("read failed:"); 95 continue; 96 } 97 else if(ret==0) 98 { 99 printf("client closed\n"); 100 FD_CLR(fd,&set);//将监听的文件描述符集合中移除. 101 close(fd); 102 continue; 103 } 104 else 105 { 106 printf("ret=%d buf=%s\n",ret,buf); 107 } 108 } 109 } 110 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<sys/socket.h> 2 #include<sys/types.h> 3 #include<stdio.h> 4 #include<netinet/in.h> 5 #include<arpa/inet.h> 6 #include<errno.h> 7 #include<string.h> 8 #include<stdlib.h> 9 #include<unistd.h> 10 int main(int argc,char ** argv) 11 { 12 //int socket(int domain, int type, int protocol); 13 int sockfd; 14 sockfd=socket(AF_INET,SOCK_STREAM,0); 15 printf("sockfd=%d\n",sockfd); 16 17 /* 18 int connect(int sockfd, struct sockaddr *serv_addr, int addrlen ); 19 作用:向服务器请求三次握手 20 参数1:套接字 21 参数2:服务端的地址族结构,也就是地址类型,IP,端口 22 参数3:服务端地址族的大小 23 返回值:成功则返回非负数 24 */ 25 26 struct sockaddr_in seraddr; 27 seraddr.sin_family=AF_INET; 28 seraddr.sin_port=htons(atoi(argv[1])); 29 inet_pton(AF_INET,"192.168.6.11",&seraddr.sin_addr.s_addr); 30 31 int ret=connect(sockfd,(struct sockaddr *)&seraddr,sizeof(seraddr)); 32 if(ret<0) 33 { 34 perror("connect failed:"); 35 exit(0); 36 } 37 char buf[20]; 38 scanf("%s",buf); 39 write(sockfd,buf,strlen(buf)+1); 40 close(sockfd); 41 42 return 0; 43 }
gcc ./server ./client 效果如下