Linux 編程之解決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 }

https://www.cnblogs.com/CodeMIRACLE/p/5122063.html複製代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章