標籤:des style http color 使用 width
今天寫一個簡單的socket網路通訊的程式的時候,用ctrl+c結束伺服器端程式之後,再次啟動伺服器出現了bind failed:the address already in use的錯誤。在網上查了一下以後找到了原因,在此記錄一下。這個IBM的官網上說到了這一點:http://www.ibm.com/developerworks/cn/linux/l-sockpit/。詳細介紹如下:
bind 普遍遭遇的問題是試圖綁定一個已經在使用的連接埠。該陷阱是也許沒有活動的通訊端存在,但仍然禁止綁定連接埠(bind 返回EADDRINUSE),它由 TCP 通訊端狀態 TIME_WAIT 引起。該狀態在通訊端關閉後約保留 2 到 4 分鐘。在 TIME_WAIT 狀態退出之後,通訊端被刪除,該地址才能被重新綁定而不出問題。
等待 TIME_WAIT 結束可能是令人惱火的一件事,特別是如果您正在開發一個通訊端伺服器,就需要停止伺服器來做一些改動,然後重啟。幸運的是,有方法可以避開 TIME_WAIT 狀態。可以給通訊端應用 SO_REUSEADDR 通訊端選項,以便連接埠可以馬上重用。
考慮清單 3 的例子。在綁定地址之前,我以 SO_REUSEADDR 選項調用 setsockopt。為了允許地址重用,我設定整型參數(on)為 1 (不然,可以設為 0 來禁止地址重用)。
清單 3.使用 SO_REUSEADDR 通訊端選項避免地址使用錯誤
int sock, ret, on;struct sockaddr_in servaddr;/* Create a new stream (TCP) socket */sock = socket( AF_INET, SOCK_STREAM, 0 ):/* Enable address reuse */on = 1;ret = setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) );/* Allow connections to port 8080 from any available interface */memset( &servaddr, 0, sizeof(servaddr) );servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl( INADDR_ANY );servaddr.sin_port = htons( 45000 );/* Bind to the address (interface/port) */ret = bind( sock, (struct sockaddr *)&servaddr, sizeof(servaddr) );
在應用了 SO_REUSEADDR 選項之後,bind API 函數將允許地址的立即重用。
我按照上面的指示加入這段代碼以後又出現了一個錯誤:setsockopt failed: Socket operation on non-socket。
然後又在網上查,Socket operation on non-socket 錯誤出現有兩種情況:
1. 建立socket:
if(listenfd= socket(AF_INET,SOCK_STREAM, 0)==-1){
perror("creating socket failed!");
exit(-1);
}
會造成在bind時出現 Socket operation on non-socket錯誤
正確的代碼應該是:
if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
perror("creating socket failed!");
exit(-1);
}
2. accept時:
if(connfd=accept(listenfd,(struct sockaddr *)&client_addr,(socklen_t *)&sin_size)==-1){
perror("accept error!");
exit(-1);
}
會造成在recv時出現 Socket operation on non-socket錯誤
正確代碼是:
if((connfd=accept(listenfd,(struct sockaddr *)&client_addr,(socklen_t *)&sin_size))==-1){
perror("accept error!");
exit(-1);
}
出現Socket operation on non-socket 錯誤的原因是:
if(listenfd= socket(AF_INET,SOCK_STREAM, 0)==-1)
if(connfd=accept(listenfd,(struct sockaddr *)&client_addr,(socklen_t *)&sin_size)==-1)
這兩句中缺失了()造成的。賦值符合優先順序最低,導致listenfd和connfd在建立/串連成功是為0,不成功時為1
最後:
如 調用connect socket accept 函數出錯,可以 perror("socket"); perror("connect"); printf("%s\n",strerror(errno));都能打出具體的錯誤。
編譯結果出現如下錯誤:undefined reference to ‘pthread_create‘,應該在在編譯中要加 -lpthread參數。