回覆列表
  • 1 # 使用者1427598728300

    從題主的錯誤看是產生了錯誤,也就是提示address already in use,這是同一個地址(IP+埠)被多個套接字繫結所致的。

    我猜題主的實驗流程是這樣的:

    客戶端1繫結IP:Port,連線服務端1;客戶端2繫結IP:Port,連線服務端2;

    然後第2步的時候提示你。

    題主可能是認為在呼叫的時候再去檢查四元組是否唯一,但實際上並非如此,因為套接字繫結本地地址後, 既有可能,也有可能。如果允許2個程序繫結同一個地址,那如果這2個程序都呼叫呢?那麼就必須由函式來檢查這個伺服器是否和其他伺服器佔用了同一地址。而並不會做這件事,它的作用僅僅是把預設建立的主動套接字(客戶)轉換成被動套接字 (服務),順便指定核心維護的連線佇列的大小。

    因此如果題主是這樣進行實驗的話,並不能證明Linux客戶端不支援埠共用,而且我在Windows上做了同樣的實驗,出現同樣的錯誤

    Windows上也是出錯,這裡我列印了的錯誤碼(因為Windows上就是擺設) ,10048,參考windows-sockets-error-codes-values-and-meanings ,即錯誤WSAEADDRINUSE,意思是Address already in use。

    問題不在於Linux系統,而在於socket本身是在bind時就要檢查繫結地址是否唯一。

    補充:關於TCP的選項。

    最常見的是解決TIME_WAIT連線繼續佔用該地址的問題的,但是如果你直接啟動2個程序bind同一地址,用這個選項還是報錯。因為TCP無法啟動2臺繫結同一地址的伺服器。

    但是,首先到某地址的客戶端併成功連線伺服器,客戶端2再該地址是可行的,但是連線同一伺服器還是會報錯,只不過錯誤變成了 (Cannot assign requested address),這是導致的錯誤,即賦予客戶端的臨時埠(ephemeral port)已被佔用。

    但是繫結同一埠的客戶端可以連線其他伺服器,為了證明這點,我做了個實驗,在2臺遠端伺服器還有本地主機上運行了下面的服務端程式

    然後在本地主機分別啟動3個客戶端程式分別連線到對應伺服器

    然後檢視端口占用(這裡我手動隱藏了我的伺服器地址)

    可以發現客戶端是支援埠共用的。

  • 中秋節和大豐收的關聯?
  • 春天是個適合分手的季節嗎?