端口選擇
繼續看inet_csk_get_port函數:
在端口選擇前,先確定當前該socket的“屬性”,即是否可以端口復用,是否在TCP_LISTEN狀態,以便后面插入到桶隊列時設置fastreuse字段。
bool reuse = sk- >sk_reuse && sk- >sk_state != TCP_LISTEN;
進行端口選擇和綁定:
端口綁定分為兩種,一種指定端口,一種隨機選擇。如果給 bind 傳 遞的地址參數中,port 字段為 0,那么就會自動選擇參數。
如代碼所示,當端口port沒有指定時,調用inet_csk_find_open_port(sk, &tb, &port):
if (!port) {
head = inet_csk_find_open_port(sk, &tb, &port);
if (!head)
return ret;
if (!tb)
goto tb_not_found;
goto success;
}
主要邏輯在net_csk_find_open_port實現,重點看端口指定,暫時不看端口不指定(其實邏輯差不多)。那么當用戶指定了端口,也就是port有值時:
head = &hinfo- >bhash[inet_bhashfn(net, port,hinfo- >bhash_size)];
inet_bind_bucket_for_each(tb, &head- >chain)
if (net_eq(ib_net(tb), net) && tb- >port == port)
goto tb_found;
tb_not_found:
tb = inet_bind_bucket_create(hinfo- >bind_bucket_cachep,
net, head, port);
if (!tb)
goto fail_unlock;
tb_found:
if (!hlist_empty(&tb- >owners)) {
if (sk- >sk_reuse == SK_FORCE_REUSE)
goto success;
if ((tb- >fastreuse > 0 && reuse) ||
sk_reuseport_match(tb, sk))
goto success;
if (inet_csk_bind_conflict(sk, tb, true, true))
goto fail_unlock;
}
- 1、通過指定的port端口號,計算哈希值,找到對應的inet_bind_hashbucket:
head = &hinfo- >bhash[inet_bhashfn(net, port,hinfo- >bhash_size)];
- 2 、調用inet_bind_bucket_for_each遍歷該inet_bind_hashbucke中的chain鏈表
inet_bind_bucket_for_each(tb, &head- >chain)
- 3、如果遍歷chain鏈表時,找到了指定port相同的桶結構,則跳轉到tb_found:
if (net_eq(ib_net(tb), net) && tb- >port == port)
goto tb_found;
- 4、在tb_found標簽中:判斷該桶結構中sock隊列是否為空,為空且當前套接字支持復用,則綁定成功。進入success標簽。
- 5、在succeess完成對該port對應的桶結構的初始化或修改
- 6、如果在3、中沒有找到對應的桶結構,進入tb_not_found標簽,在當前的chain鏈表中創建一個新的桶結構,再進行4、5操作:
tb_not_found:
tb = inet_bind_bucket_create(hinfo- >bind_bucket_cachep,
net, head, port);
if (!tb)
goto fail_unlock;
端口復用的解釋
還是要從文章開頭的圖說起,bind時端口號都會經過哈希計算分配在【相應的哈希桶結構inet_bind_hashbucket】上的chain鏈表節點的【桶結構inet_bind_bucket上】,inet_bind_bucket 結構就是用來描述端口和 sock 之間的綁定關系的。它的 port 字段表示一個綁定的端口,而 owners 則表示綁定到這個端口之上的所有 sock,因為端口可以重用,所以同一端口可能有多個 sock 綁定。
bind端口復用的實際用途基本上也就是:
防止服務器重啟時之前綁定的端口還未釋放或者程序突然退出而系統沒有釋放端口。這種情況下如果設定了端口復用,則新啟動的服務器進程可以直接綁定端口。如果沒有設定端口復用,綁定會失敗,提示ADDR已經在使用中!
-
Linux
+關注
關注
87文章
11345瀏覽量
210404 -
端口
+關注
關注
4文章
990瀏覽量
32211 -
Bind
+關注
關注
0文章
5瀏覽量
7618
發布評論請先 登錄
相關推薦
評論