Linux下socket編程 address already in use 問題


  我在編寫服務端程序時,結束服務器端程序運行后,再次啟動程序,bind函數就會返回address already in use這個錯誤,提示我端口已經被占用了。

  使用 # netstat –apn | grep [port] 命令或者 lsof -i:[port] 命令查看端口的占用情況,可以發現之前被終止的服務器端程序進程仍在監聽該端口。於是用kill命令殺掉再啟動就可以正常運行了。后來在這篇文章找到了原因http://www.ibm.com/developerworks/cn/linux/l-sockpit/

  您可以使用 bind API 函數來綁定一個地址(一個接口和一個端口)到一個套接字端點。可以在服務器設置中使用這個函數,以便限制可能有連接到來的接口。也可以在客戶端設置中使用這個函數,以便限制應當供出去的連接所使用的接口。bind 最常見的用法是關聯端口號和服務器,並使用通配符地址(INADDR_ANY),它允許任何接口為到來的連接所使用。

bind 普遍遭遇的問題是試圖綁定一個已經在使用的端口。該陷阱是也許沒有活動的套接字存在,但仍然禁止綁定端口(bind 返回 EADDRINUSE),它由 TCP 套接字狀態 TIME_WAIT 引起。該狀態在套接字關閉后約保留 2 到 4 分鍾。在 TIME_WAIT 狀態退出之后,套接字被刪除,該地址才能被重新綁定而不出問題。

等待 TIME_WAIT 結束可能是令人惱火的一件事,特別是如果您正在開發一個套接字服務器,就需要停止服務器來做一些改動,然后重啟。幸運的是,有方法可以避開 TIME_WAIT 狀態。可以給套接字應用 SO_REUSEADDR 套接字選項,以便端口可以馬上重用。

  在bind函數之前添加下面的代碼即可解決問題。

1 int opt = 1;
2 if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) != 0)
3 {           
4     perror("Server setsockopt failed");
5     return 1;
6 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM