1. 程式人生 > >bind:address already in use解決方法

bind:address already in use解決方法

每次修改了原始碼並再次編譯執行時,常遇到下面的地使用錯誤:
Cann’t bind server socket !
: Address already in use
雖然用Ctrl+C強制結束了程序,但錯誤依然存在,用netstat -an |grep 5120和ps aux |grep 5120都還能看到剛才用Ctrl+C“強制結束”了的程序,埠還是使用中,只好每次用kill結束程序,很是麻煩。昨天晚上無意間瀏覽到IBM網站上的一篇題為 《 Linux套接字程式設計中的5個隱患 》的文章,恍然大悟,今天試了一下,果然解決問題,在此表示感謝,也希望更多的coder看到這篇文章,避免出錯。
主要程式碼為:

      int reuse = 0;
      struct sockaddr_in cliaddr, servaddr;

       listenfd = socket(PF_INET, SOCK_STREAM,0);
       if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
       {
                perror(“setsockopet error\n”);
                return -1;
       }

//當我修改一個檔案要再次make的時候,要先make clean 然後再make;

現在我每次用Ctrl+C強制結束程序後,用netstat和ps都還能看到埠在使用中,但執行程式不會出現”Address already in use”的錯誤了,實現了埠的重用。以下是原文中的第三個隱患--地址使用錯誤地址使用錯誤(EADDRINUSE)您可以使用 bind API 函式來繫結一個地址(一個介面和一個埠)到一個套接字端點。可以在伺服器設定中使用這個函式,以便限制可能有連線到來的介面。也可以在客戶端設定中使用這個函式,以便限制應當供出去的連線所使用的介面。bind 最常見的用法是關聯埠號和伺服器,並使用萬用字元地址(INADDR_ANY),它允許任何介面為到來的連線所使用。bind 普遍遭遇的問題是試圖繫結一個已經在使用的埠。該陷阱是也許沒有活動的套接字存在,但仍然禁止繫結埠(bind 返回 EADDRINUSE),它由 TCP 套接字狀態TIME_WAIT 引起。該狀態在套接字關閉後約保留 2 到 4 分鐘。在 TIME_WAIT 狀態退出之後,套接字被刪除,該地址才能被重新繫結而不出問題。等待 TIME_WAIT 結束可能是令人惱火的一件事,特別是如果您正在開發一個套接字伺服器,就需要停止伺服器來做一些改動,然後重啟。幸運的是,有方法可以避開 TIME_WAIT狀態。可以給套接字應用 SO_REUSEADDR 套接字選項,以便埠可以馬上重用。

方法2:

linux% netstat -tanlp

linux% kill (pid)

可以切斷有此埠號的程序。

另一個要點是:我一直以為伺服器和客戶要在不同的視窗中。其實不用。

linux% ./tcpserv03 & 

linux% ./tcpcli04 127.0.0.1

就可以讓伺服器在後臺執行,客戶端在前臺執行,按照書上的程式碼就可以看到所有結果了。