關於bind錯誤的處理:
bind: Address already in use服務器
緣由: 操做系統沒有當即釋放端口網絡
解決一: 等待一段時間運行網絡程序便可併發
解決二:經過setsockopt進行設置,關鍵代碼以下。socket
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 }
舉例:以多進程併發服務器爲例tcp
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 }