端口復(fù)用最常用的用途應(yīng)該是防止服務(wù)器重啟時(shí)之前綁定的端口還未釋放或者程序突然退出而系統(tǒng)沒(méi)有釋放端口。此時(shí)如果設(shè)定了端口復(fù)用,
則新啟動(dòng)的服務(wù)器進(jìn)程可以直接綁定端口。如果沒(méi)有設(shè)定端口復(fù)用,綁定會(huì)失敗,提示ADDR已經(jīng)在使用中——那只好等等再重試了。
在TCP斷開鏈接時(shí)需要四次握手來(lái)斷開,當(dāng)兩端都關(guān)閉了read/write通道以后還是要等待一個(gè)TIME_WAIT時(shí)間(作用是在網(wǎng)絡(luò)中殘余的TCP包消失)。
一般來(lái)說(shuō),一個(gè)端口釋放后會(huì)等待兩分鐘之后或三十秒才能再被使用,SO_REUSEADDR是讓端口釋放后立即就可以被再次使用。
SO_REUSEADDR套接字選項(xiàng)通知內(nèi)核,如果TCP狀態(tài)位于 TIME_WAIT ,可以重用端口。如果TCP狀態(tài)位于其他狀態(tài),重用端口時(shí)依舊得到一個(gè)錯(cuò)誤信息,指明"地址已經(jīng)使用中"。如果你的服務(wù)程序停止后想立即重啟,而新套接字依舊使用同一端口,此時(shí)SO_REUSEADDR 選項(xiàng)非常有用。必須意識(shí)到,此時(shí)任何非期望數(shù)據(jù)到達(dá),都可能導(dǎo)致服務(wù)程序反應(yīng)混亂,不過(guò)這種可能,事實(shí)上幾率很小。
套接字由相關(guān)五元組構(gòu)成,協(xié)議、本地地址、本地端口、遠(yuǎn)程地址、遠(yuǎn)程端口。SO_REUSEADDR 僅僅表示可以重用本地本地地址、本地端口,整個(gè)相關(guān)五元組還是唯一確定的。
應(yīng)用方法:所有TCP服務(wù)器中,在調(diào)用bind之前設(shè)置SO_REUSEADDR套接口選項(xiàng);
int bOptval=1;
int retSetsockopt=setsockopt(gServerListenSock,SOL_SOCKET ,SO_REUSEADDR ,(char *)&bOptval,sizeof(bOptval));
if (SOCKET_ERROR==retSetsockopt)
{
return 0;
}
端口復(fù)用允許在一個(gè)應(yīng)用程序可以把 n 個(gè)套接字綁在一個(gè)端口上而不出錯(cuò)。同時(shí),這 n 個(gè)套接字發(fā)送信息都正常,沒(méi)有問(wèn)題。
但是,這些套接字并不是所有都能讀取信息,只有最后一個(gè)套接字會(huì)正常接收數(shù)據(jù),這個(gè)特性都為后門程序所應(yīng)用.
SO_EXCLUSIVEADDRUSE和SO_REUSEPORT作用相反,不允許使用 端口復(fù)用,但這個(gè)參數(shù)只存在于windows中。
注意:如果是服務(wù)器,新老socket都要加SO_REUSEADDR參數(shù);要想同地址同端口綁定,只能用在udp的多播。