TCP Fast Open原理和使用

2021-10-07 18:39:55 字數 1896 閱讀 7499

tcp建立連線需要三次握手,這個大家都知道。但是三次握手會導致傳輸效率下降,尤其是http這種短連線的協議,雖然http有keep-alive來讓一些請求頻繁的http提高效能,避免了一些三次握手的次數,但是還是希望能繞過三次握手提高效率,或者說在三次握手的同時就把資料傳輸的事情給做了,這就是我們這次要說的tcp fast open,簡稱tfo。

首先我們回顧一下三次握手的過程:

這裡客戶端在最後ack的時候,完全可以把想要傳送的第一條資料也一起帶過去,所以這是tfo做的其中乙個優化方案。然後還參考了http登入態的流程,採用cookie的方案,讓服務端知道某個客戶端之前已經「登入」過了,那麼它發過來的資料就可以直接接收了,不必要一開始必須三次握手後再發資料。

當客戶端第一次連線服務端時,是沒有cookie的,所以會傳送乙個空的cookie,意味著要請求cookie,如下圖:

這樣服務端就會將cookie通過syn+ack的路徑返回給客戶端,客戶端儲存後,將傳送的資料三次握手的最後一步ack同時傳送給服務端。

當客戶端斷開連線,下一次請求同乙個服務端的時候,會帶上之前儲存的cookie和要傳送的資料,在syn的路徑上一起傳送給服務端,如下圖:

這樣之後每次握手的時候還同時傳送了資料資訊,將資料傳輸提前了。服務端只要驗證了cookie,就會將傳送的資料接收,否則會丟棄並且再通過syn+ack路徑返回乙個新的cookie,這種情況一般是cookie過期導致的。

tfo是需要開啟的,開啟引數在:

/proc/sys/net/ipv4/tcp_fastopen

0:關閉

1:作為客戶端使用fast open功能,預設值

2:作為服務端使用fast open功能

3:無論是客戶端還是服務端都使用fast open功能

並且如果之前的**沒有做這方面的處理,也是不能使用的,從上面的流程圖就能看到,客戶端是在連線的過程就傳送資料,但是之前客戶端都是先呼叫connect成功後,才用send傳送資料的。

服務端需要對listen的socket設定如下選項:

//需要的標頭檔案

#include..

....

int qlen =5;

//fast open 佇列

setsockopt

(m_listen_socket, ipproto_tcp, tcp_fastopen,

&qlen,

sizeof

(qlen)

);

客戶端則直接使用sendto方法進行連線和傳送資料,示例**如下:

#include

#include

#include

#include

#include

#include

#include

intmain()

char buf[

100]=;

recv

(sfd, buf,

100,0)

;printf

("%s\n"

, buf)

;close

(sfd)

;}

經過試驗,客戶端儲存的cookie是跟服務端的ip繫結的,而不是跟程序或埠繫結。當客戶端程式傳送到同乙個ip但是不同埠的程序時,使用的是同乙個cookie,而且服務端也認證成功。

頭條面試題 Redis Redis的原理和使用

redis是高效能的key value資料庫 redis支援資料的持久化,即將記憶體中的資料存數在磁碟中,重啟的時候再次載入進行使用 redis支援master salve模式的資料備份 redis所有的操作都是原子性的,即要麼成功執行要麼不執行 redis支援豐富的特性,支援publish sub...

apply call bind和this的使用

立即呼叫fun,同時將fun函式原來的this指向傳入的新context物件,實現同乙個方法在不同物件上重複使用。context 傳入的物件,替代fun函式原來的this argsarray 乙個陣列或者類陣列物件,其中的陣列引數會被展開作為單獨的實參傳給 fun 函式,需要注意引數的順序。fun....

NVARCHAR 和VARCHAR區別和使用

1 各自的定義 nvarchar n 包含 n 個字元的可變長度 unicode 字元資料。n 的值必須介於 1 與 4,000 之間。位元組的儲存大小是所輸入字元個數的兩倍。所輸入的資料字元長度可以為零。varchar n 長度為 n 個位元組的可變長度且非 unicode 的字元資料。n 必須是...