ESP32中 SO_REUSEADDR 設置(socket返回118錯誤解決方法)

1、一般來說,一個端口釋放後會等待兩分鐘之後才能再被使用,SO_REUSEADDR是讓端口釋放後立即就可以被再次使用。

    SO_REUSEADDR用於對TCP套接字處於TIME_WAIT狀態下的socket,纔可以重複綁定使用。server程序總是應該在調用bind()之前設置SO_REUSEADDR套接字選項。TCP,先調用close()的一方會進入TIME_WAIT狀態

2、SO_REUSEADDR和SO_REUSEPORT

SO_REUSEADDR提供如下四個功能:

    SO_REUSEADDR允許啓動一個監聽服務器並捆綁其衆所周知端口,即使以前建立的將此端口用做他們的本地端口的連接仍存在。這通常是重啓監聽服務器時出現,若不設置此選項,則bind時將出錯。

    SO_REUSEADDR允許在同一端口上啓動同一服務器的多個實例,只要每個實例捆綁一個不同的本地IP地址即可。對於TCP,我們根本不可能啓動捆綁相同IP地址和相同端口號的多個服務器。

    SO_REUSEADDR允許單個進程捆綁同一端口到多個套接口上,只要每個捆綁指定不同的本地IP地址即可。這一般不用於TCP服務器。

    SO_REUSEADDR允許完全重複的捆綁:當一個IP地址和端口綁定到某個套接口上時,還允許此IP地址和端口捆綁到另一個套接口上。一般來說,這個特性僅在支持多播的系統上纔有,而且只對UDP套接口而言(TCP不支持多播)。

SO_REUSEPORT選項有如下語義:

    此選項允許完全重複捆綁,但僅在想捆綁相同IP地址和端口的套接口都指定了此套接口選項才行。

    如果被捆綁的IP地址是一個多播地址,則SO_REUSEADDR和SO_REUSEPORT等效。

使用這兩個套接口選項的建議:

    在所有TCP服務器中,在調用bind之前設置SO_REUSEADDR套接口選項;

當編寫一個同一時刻在同一主機上可運行多次的多播應用程序時,設置SO_REUSEADDR選項,並將本組的多播地址作爲本地IP地址捆綁。

    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,

   (const void *)&nOptval , sizeof(int)) < 0) ...

    Q:編寫 TCP/SOCK_STREAM 服務程序時,SO_REUSEADDR到底什麼意思?

    A:這個套接字選項通知內核,如果端口忙,但TCP狀態位於 TIME_WAIT ,可以重用端口。如果端口忙,而TCP狀態位於其他狀態,重用端口時依舊得到一個錯誤信息,指明"地址已經使用中"。如果你的服務程序停止後想立即重啓,而新套接字依舊使用同一端口,此時SO_REUSEADDR 選項非常有用。必須意識到,此時任何非期望數據到達,都可能導致服務程序反應混亂,不過這只是一種可能,事實上很不可能。

    一個套接字由相關五元組構成,協議、本地地址、本地端口、遠程地址、遠程端口。SO_REUSEADDR 僅僅表示可以重用本地本地地址、本地端口,整個相關五元組還是唯一確定的。所以,重啓後的服務程序有可能收到非期望數據。必須慎重使用 SO_REUSEADDR 選項。

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