當網路中一台主機向本地主機發起tcp連線請求時,它所發出的第乙個tcp資料報是乙個syn,並帶上自己的isn(初始序號)。該資料報會被送往本地主機協議棧的mytcp_v4_rcv函式,該函式對資料進行一些基本的正確性檢查後,從mytcp_hashinfo雜湊表集中,尋找應當處理這個連線請求的socket。
首先在ehash表的前半部分中查尋,即在處於tcp_establish狀態的socket中查尋匹配。匹配邏輯是:socket結構體成員sk_hash要等於根據請求資料報的目的位址和源位址等資訊計算出來的雜湊值,資料報的目的位址等於本地socket的接收源位址,資料報的源位址等於本地socket的目的位址,資料的源埠和目的埠與本地socket的目的埠與源埠匹配,並且,如果本地socket繫結了輸入網路裝置介面,那資料報的輸入介面要跟本地socket的輸入介面相同。可見,ehash表中的socket匹配是乙個非常嚴格的完全匹配的過程,在前半部分沒有找到,則到後半部分在time_wait狀態的socket中繼續尋找。
因為這是乙個連線請求,所以在ehash表中是不可能找到匹配的socket的。接下來到listening_hash中尋找偵聽socket。只要目的位址和埠匹配,如果偵聽socket繫結了輸入介面,輸入介面也匹配,則尋找成功。
找到乙個偵聽socket後,首先在這個socket的accept佇列(struct inet_connection_sock->icsk_accept_queue)中尋找匹配的request_sock,因為有可能該請求已經被接受,並儲存在接受佇列中了(但還沒有被accept處理,因為如果accept處理過了,會出現在ehash表中)。下面先看一下request_sock結構體的定義:
struct request_sock ;
struct inet_request_sock是request_sock的擴充套件,其定義如下:
struct inet_request_sock ;
尋找request_sock的邏輯是請求資料的源位址和埠跟rmt_addr和rmt_port匹配,目的位址跟loc_addr匹配。顯然,對於剛剛發起第乙個syn的socket請求來講,這種尋找總是失敗的,它不可能已經在接受佇列中存在。
接下來到ehash表中去查詢匹配的socket,顯然這種查詢也是注定要失敗的。
沒有找到任何socket,我們繼續處理這個偵聽socket本身,它當前處於tcp_listen狀態,並且收到了來自網路對端的第乙個syn資料報,所以,我們為其呼叫mytcp_v4_conn_request,接受這個連線請求。mytcp_v4_conn_request首先檢查這個請求資料報,如果是廣播包或組播包,則直接丟棄,不進行處理。如果請求佇列已滿(即struct inet_connection_sock->isck_accept_queue->listen_sock中的request_sock佇列),則不進行處理。如果接受佇列已滿(sock->sk_ack_backlog > sock->sk_max_ack_backlog)並且listen_sock->qlen_young大於1,則不進行處理。否則,在記憶體中建立乙個struct request_sock。
建立了struct request_sock後,首先分析請求資料報的tcp選項,將分析得到的值存入struct inet_request_sock。然後為rmt_addr, rmt_port, loc_addr賦值,然後儲存ip選項
mytcp_v4_conn_request函式對於接受tcp連線請求的處理,它在建立了乙個struct request_sock之後,需要生成乙個isn(初始序號)。先來看一下struct tcp_request_sock結構體,它是對inet_request_sock的擴充套件:
struct tcp_request_sock ;
它增加了兩個成員,snt_isn是本地socket用於跟接受的連線請求進行tcp通訊的初始序號。rcv_isn是來自對端的初始序號。
有了isn後,對請求socket發出的syn發回乙個ack跟本地的syn。然後把建立的struct request_sock加入到偵聽socket的請求socket雜湊表中(struct inet_connection_sock->isck_accept_queue->listen_opt->syn_table)>,但是需要注意的是,此時該request_sock還沒有進入接受佇列(即通過struct inet_connection_sock->isck_accept_queue->rskq_accept_head還不能找到它)。
接下來,當遠端的socket收到來自本地socket的ack+syn後,會發回來乙個ack。繼續走tcp資料報的接收流程。此時我們還是只能在mytcp_hashinfo雜湊表集中的listening_hash表中找到偵聽socket對它進行處理。但此時,我們可以在偵聽socket的syn_table表中找到這個request_sock。
找出這個request_sock後,要對它進行檢查,檢查通過,從偵聽socket上新轉殖乙個strcut tcp_sock,置其狀態為tcp_syn_recv,放入mytcp_hashinfok中的ehash雜湊表,然後把該新建立的tcp_sock也繫結在跟偵聽埠相同的本地埠上。將request_sock從syn_table中取走,令request_sock->sk等於新建立的struct tcp_sock。把request_sock加入接受佇列。
最後,把socket的狀態改為tcp_establish,接受乙個tcp連線請求的過程結束。
accept系統呼叫把socket從接受佇列中取走,取回request_sock->sk,並釋放掉request_sock,然後就可以進行tcp通訊了。
TCP資料報的接收過程
1,一般網絡卡接收資料是以觸發中斷來接收的,在網絡卡driver中,接收到資料時,往kernel的api netif rx 丟 2,接著資料被送到ip層ip local deliver finish 經過剝離ip頭部,把資料往tcp層發 3,tcp層tcp v4 rcv 收到資料後,再呼叫tcp r...
訊號接收過程
一 通過天線接收 二 saw filter聲表面濾波器 saw filter聲表面波元件主要作用原理是利用壓電材料的壓電特性,利用輸入與輸出換能器 transducer 將電波的輸入訊號轉換成機械能,經過處理後,再把機械能轉換成電的訊號,以達到過濾不必要的訊號及雜訊,提公升收訊品質的目標。聲表濾波器...
組播發送接收過程
組播發送過程 ip 多點廣播允許應用程式傳送網路中的一組主機可以接收到的單個 ip 資料報。該組中的主機可能駐留在單個子網中,也可能駐留在連線可使用多點廣播的路由器的不同子網中。主機可以隨時加入或離開組。對主機組中的成員位置或數目沒有任何限制。範圍在 224.0.0.1 到239.255.255.2...