Linux網絡編程(二) —— SO_REUSEADDR套接字選項

目錄

提問:

用來解決什麼問題?

如何使用?

參考資料


提問:

  1. 用來解決什麼問題?
  2. 如何使用?

用來解決什麼問題?

  1. 避免當TCP服務器重啓時,嘗試將套接字綁定到當前已經同TCP結點相關聯的端口上時出現的EADDRINUSE(地址已使用)錯誤。這個問題會在下面兩種情況中出現:
    a   之前連接到客戶端的服務器要麼通過close(),要麼因爲崩潰(被信號殺死)而執行了主動關閉。這使得TCP結點將處於TIME_WAIT狀態,直到2倍的MSL超時過期爲止(不同系統下,不一樣。ubuntu 總時長是 1分鐘)。
    b   之前,服務器先創建一個子進程來處理客戶端的連接。稍後,服務器終止,而子進程繼續服務客戶端,因而使得維護的TCP結點使用了服務器的知名端口號。
    儘管如此,針對上述兩種情況,默認情況下大多數TCP實現會阻止新的監聽套接字綁定到服務器知名端口上。
  2. 一個已連接的TCP套接字是由一個4元組來唯一標識的。形式如下:
    { local-IP-address, local-port, foreign-IP-address, foreign-port}
    TCP規範要求這樣一個4元組是唯一的,也就是說只有一個對應的連接可以存在。
    而大多數實現(包括Linux)都強制施加了一個更爲嚴格的約束:如果主機上有任何可匹配到本地端口的TCP連接,則本地端口不能被重用(對bind()的調用)。

如何使用?

  • 啓用SO_REUSEADDR套接字選項可以解放這個限制,使得更接近TCP需求。默認情況下該選項值爲0,表示被關閉。我們可以在綁定套接字之前爲該選項設定一個非零值來啓用它。下面是栗子^_^:
#include <fun.c>    //頭文件在之前的博客中有

int main()
{
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if(-1 == fd)
    {
        perror("socket");
    }
    
    int optval = 1;
    if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1)
        perror("setsockopt");

    if(bind(fd, &addr, addrlen) == -1)
        perror("bind");

    if(listen(fd, 10) == -1)
        perror("listen");

    return 0;
}

 

 

 

參考資料

  1. linux/UNIX系統編程手冊 (下冊)

 

 

 

 

 

 

 

 

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