解决bind错误 bind: Address already in use
关于bind错误的处理:
bind: Address already in use
原因: 操作系统没有立即释放端口
解决一: 等待一段时间运行网络程序即可
解决二:通过setsockopt进行设置,关键代码如下。
1 // 解决在close之后会有一个WAIT_TIME,导致bind失败的问题 2 int val = 1; 3 int ret = setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,(void *)&val,sizeof(int)); 4 if(ret == -1) 5 { 6 printf("setsockopt"); 7 exit(1); 8 }
举例:以多进程并发服务器为例
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 #include <sys/types.h> 6 #include <sys/socket.h> 7 #include <netinet/in.h> 8 #include <arpa/inet.h> 9 #include <signal.h> 10 11 #define PORT 7788 12 13 int init_tcp() 14 { 15 // 1.创建套接字 - 设置协议 16 int sfd = socket(AF_INET,SOCK_STREAM,0); 17 if( -1 == sfd ) 18 { 19 perror("socket"); 20 exit(-1); 21 } 22 //2. 解决在close之后会有一个WAIT_TIME,导致bind失败的问题 23 int val = 1; 24 int ret = setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,(void *)&val,sizeof(int)); 25 if(ret == -1) 26 { 27 printf("setsockopt"); 28 exit(1); 29 } 30 //3. 绑定IP和PORT 31 struct sockaddr_in saddr; 32 saddr.sin_family = AF_INET; 33 saddr.sin_addr.s_addr = INADDR_ANY; 34 saddr.sin_port = htons(PORT); 35 ret = bind(sfd,(struct sockaddr *)&saddr,sizeof(saddr)); 36 if(ret == -1) 37 { 38 printf("bind"); 39 exit(1); 40 } 41 //4. 监听 42 ret = listen(sfd,5); 43 if(ret == -1) 44 { 45 printf("listen"); 46 exit(1); 47 } 48 printf("Server is ready ... \n"); 49 50 return sfd; 51 } 52 53 void deal_communication(int cfd) 54 { 55 char buf[64] = {'\0'}; 56 while(1) 57 { 58 memset(buf,'\0',sizeof(buf)); 59 recv(cfd,buf,sizeof(buf),0); 60 printf("client say:%s\n",buf); 61 send(cfd,buf,strlen(buf),0); 62 if(strncmp(buf,"quit",4) == 0) 63 break; 64 } 65 66 return ; 67 } 68 69 70 int main() 71 { 72 //1. 初始化(创建套接字socket/地址复用+bind/listen) 73 int sfd = init_tcp(); 74 //2. 并发处理客户端(accept / fork) 2-2通信 75 while(1) 76 { 77 int cfd = accept(sfd,NULL,NULL); 78 if(cfd == -1) 79 { 80 perror("accept"); 81 exit(1); 82 } 83 84 // fork - create a child process 85 if(fork() == 0) 86 { 87 deal_communication(cfd); 88 close(cfd); 89 exit(0); 90 } 91 close(cfd); 92 signal(SIGCHLD,SIG_DFL); 93 } 94 close(sfd); 95 return 0; 96 }