服务器端重启后会出现地址被占用的情况,主要原因是程序调用bind后的地址没被释放,服务端程序处于TIME_WAIT状态,用netstat -an|grep TIME_WAIT可以查看到,所以服务器端在绑定端口前要进行地址重用操作
1 #include<stdio.h> 2 #include <sys/types.h> /* See NOTES */ 3 #include <sys/socket.h> 4 #include <netinet/ip.h> 5 #include <errno.h> 6 #include <stdlib.h> 7 #include <netinet/in.h> 8 #include <arpa/inet.h> 9 #include <unistd.h> 10 #include <string.h> 11 12 int main(){ 13 int socketfd; 14 socketfd=socket(PF_INET,SOCK_STREAM,0); 15 if(socketfd<0){ 16 perror("socket"); 17 exit(EXIT_FAILURE); 18 } 19 20 struct sockaddr_in sockaddress; 21 sockaddress.sin_family=AF_INET; 22 sockaddress.sin_port=htons(5188); 23 sockaddress.sin_addr.s_addr=htonl(INADDR_ANY);//INADDR_ANY接收任何地址的连接 24 //sockaddress.sin_addr.s_addr=inet_addr("127.0.0.1");//也可以是这种方式 25 26 int on=1; 27 if (setsockopt(socketfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))<0){ 28 perror("setsockopt"); 29 exit(EXIT_FAILURE); 30 } 31 32 if(bind(socketfd,(struct sockaddr*)&sockaddress,sizeof(sockaddress))<0){ 33 perror("bind"); 34 exit(EXIT_FAILURE); 35 } 36 37 if ( listen(socketfd,SOMAXCONN)<0){ 38 perror("listen"); 39 exit(EXIT_FAILURE); 40 } 41 42 int conn; 43 struct sockaddr_in peeraddr; 44 socklen_t len=sizeof(struct sockaddr_in); 45 conn=accept(socketfd,(struct sockaddr*)&peeraddr,&len); 46 if (conn<0){ 47 perror("accept"); 48 exit(EXIT_FAILURE); 49 } 50 printf("client ip:%s port:%d\n",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port)); 51 52 char recvbuffer[1024]; 53 while(1){ 54 memset(recvbuffer,0,sizeof(recvbuffer)); 55 read(conn,&recvbuffer,sizeof(recvbuffer)); 56 fputs(recvbuffer,stdout); 57 write(conn,recvbuffer,strlen(recvbuffer)); 58 } 59 close(socketfd); 60 close(conn); 61 62 return 0; 63 64 }
请关注这一句:
setsockopt(socketfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)