linux 網路編程 socket bind failed 問題解決

來源:互聯網
上載者:User

標籤: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參數。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.