網絡編程---TCP協議

TCP協議基礎知識

TCP(Transmission Control Protocol,傳輸控制協議)是互聯網核心協議之一,位于傳輸層(OSI第4層),為應用層提供可靠的、面向連接的、基于字節流的數據傳輸服務。它與IP協議共同構成TCP/IP協議棧的基礎。

TCP的核心特性

  • 面向連接

    • 通信前需通過三次握手建立連接,結束后通過四次揮手釋放連接。

    • 每個連接由四元組(源IP、源端口、目的IP、目的端口)唯一標識。

  • 可靠性

    • 序列號與確認應答(ACK):每個字節數據都有編號,接收方通過ACK確認已收到的數據。

    • 超時重傳:未收到ACK時,發送方會重傳數據。

    • 數據校驗:通過校驗和(Checksum)檢測傳輸錯誤。

    • 流量控制:通過滑動窗口機制動態調整發送速率,避免接收方緩沖區溢出。

    • 擁塞控制:通過算法(如慢啟動、擁塞避免、快重傳、快恢復)防止網絡過載。

  • 字節流服務

    • 應用層數據被TCP視為無結構的字節流,不保留消息邊界(需應用層自行解析,如HTTP的Content-Length或分塊傳輸)。

  • 全雙工通信

    • 連接雙方可同時發送和接收數據。

TCP協議報文結構

字段名位數/字節數說明
源端口16 位發送端的端口號
目的端口16 位接收端的端口號
序號(seq)32 位本報文段第一個字節的序列號
確認號(ack)32 位期望收到的下一個字節序號
數據偏移4 位TCP首部長度(單位:4字節),最大60字節
保留6 位保留字段,必須為0
控制位6 位包括 URG、ACK、PSH、RST、SYN、FIN
窗口16 位接收窗口大小(流量控制)
檢驗和16 位校驗TCP首部和數據
緊急指針16 位在 URG=1 時有效,指出緊急數據的末尾

  • 1.ACK(Acknowledgment 標志位) 是控制位里的一個“開關”。
  • 只有 ACK=1 時,32 bit 數字才有效。?
  • 2.確認號(Acknowledgment Number) 是一個 32 bit 的“數值”。
  • 期望收到的下一個字節序號
  • 換句話說,它表示“序號 ≤ 確認號-1 的所有字節我都收齊了”。
  • 只有當 ACK = 1 時才有效。

eg:

ACK=1, Ack=1001?含義:
“我(接收方)已經收到了 1000 及以前的全部數據,請你(發送方)下一幀從 1001 開始發。”

TCP首部(可變部分)
  • 選項(Options):長度可變(最多40字節),常見選項包括:

    • MSS(最大報文段長度)

    • 時間戳(Timestamps)

    • 窗口擴大因子(Window Scale)

  • 填充(Padding):用于補齊至4字節倍數

TCP數據部分
  • 實際傳輸的應用層數據(如HTTP請求、FTP命令等)

整體結構層次

  • IP首部:包含源/目的IP地址、TTL、協議類型(TCP=6)等

  • IP數據部分:整個TCP報文段(TCP首部 + TCP數據)

TCP--三次握手和四次揮手

TCP協議的三次握手和四次揮手是TCP建立和斷開連接的兩個重要過程,它們確保了數據傳輸的可靠性和連接的正確管理。

一、三次握手

定義: 三次握手(Three-way Handshake)是TCP協議用來建立可靠連接的過程。它需要客戶端和服務器之間發送三個數據包來完成連接的建立。

目的

  • 確認雙方的接收能力和發送能力是否正常。

  • 同步雙方的序列號(Sequence Number)和確認號(Acknowledgment Number)。

  • 為后續的可靠傳輸做準備。

過程 設客戶端為A,服務器端為B

步驟發送方接收方描述
第一次握手ABA向B發送一個SYN報文,標志位SYN=1,序列號seq=x。表示A希望與B建立連接。
第二次握手BAB收到A的SYN報文后,發送一個SYN+ACK報文作為響應。SYN=1,ACK=1,序列號seq=y,確認號ack=x+1。表示B同意連接,并將A的序列號加1確認。
第三次握手ABA收到B的SYN+ACK報文后,發送一個ACK報文。ACK=1,序列號seq=x+1,確認號ack=y+1。表示A確認收到B的響應,連接建立完成。

為什么需要三次握手?

三次握手的主要目的是防止失效的連接請求報文突然到達服務器,從而產生錯誤。如果采用兩次握手,可能會出現以下問題:

  • 客戶端發送的連接請求報文可能因為網絡延遲而滯留,未能及時到達服務器。

  • 當客戶端再次發送連接請求并成功建立連接后,第一次發送的報文可能突然到達服務器。

  • 如果采用兩次握手,服務器會誤認為客戶端又發送了一次連接請求,從而建立一個無效的連接。

  • 這種情況下,客戶端會忽略服務器的確認,也不發送數據,導致不必要的錯誤和網絡資源浪費。

  • 而采用三次握手,即使失效的報文到達服務器,服務器會發送確認報文,但客戶端不會確認,服務器因此知道客戶端沒有請求連接。

二、四次揮手

定義: 四次揮手(Four-way Wavehand)是TCP協議用來斷開連接的過程。它需要客戶端和服務器之間發送四個數據包來確認連接的斷開。

過程 設客戶端為A,服務器端為B

步驟發送方接收方描述
第一次揮手ABA發送一個FIN報文,標志位FIN=1,表示A希望關閉連接。A進入FIN_WAIT_1狀態。
第二次揮手BAB收到A的FIN報文后,發送一個ACK報文作為響應。ACK=1,確認號ack為A的序列號加1。B進入CLOSED_WAIT狀態。
第三次揮手BAB在處理完未完成的發送請求后,發送一個FIN報文給A,表示B也準備關閉連接。B進入LAST_ACK狀態。
第四次揮手ABA收到B的FIN報文后,發送一個ACK報文作為響應。ACK=1,確認號ack為B的序列號加1。A進入TIME_WAIT狀態。B進入CLOSED狀態,完成連接關閉。
客戶端狀態變化A在經過2MSL(最大報文段生存時間)后,進入CLOSED狀態,完成連接關閉。

為什么需要四次揮手?

  • 在TCP連接中,數據的發送是雙向的,客戶端和服務器可能都有未發送或未接收的數據。

  • 當一方(如客戶端)發送FIN報文請求關閉連接時,另一方(如服務器)可能還有未處理完的數據。

  • 因此,服務器需要先發送ACK確認收到關閉請求,然后在處理完數據后再發送自己的FIN報文。

  • 客戶端收到服務器的FIN報文后,也需要發送ACK確認,確保服務器知道客戶端已經收到關閉請求。

  • 這樣,雙方都需要兩次確認,因此總共需要四次揮手。

客戶端為什么要等待2MSL?

  • 2MSL(兩倍最大報文段生存時間)是任何報文在網絡上存在的最長時間。

  • 客戶端在發送最后一個ACK報文后,需要等待2MSL時間,以確保這個ACK報文能夠到達服務器。

  • 如果ACK報文丟失,服務器會重新發送FIN報文,客戶端可以再次發送ACK報文。

  • 等待2MSL時間可以確保舊連接的報文不會影響新連接的建立。

三、總結

  • 三次握手:用于建立TCP連接,確保雙方的發送和接收能力正常,同步序列號和確認號。

  • 四次揮手:用于斷開TCP連接,確保雙方都處理完未完成的發送請求,安全地關閉連接。

  • 三次握手的原因:防止失效的連接請求報文導致錯誤連接。

  • 四次揮手的原因:確保雙方都能處理完未完成的發送請求,避免數據丟失或錯誤。

通過三次握手和四次揮手,TCP協議能夠實現可靠、有序、無丟失的數據傳輸。

TCP數據傳輸

可靠傳輸保障------四大機制 + 三類算法 + 兩套定時器

TCP 通過“編號-確認-重傳-窗口-校驗”四大機制,輔以“滑動窗口、流量控制、擁塞控制”三類算法,加上“重傳定時器、持續定時器”兩套計時器,實現 100 % 可靠、按序、無差錯的數據傳輸。

一、四大機制:可靠傳輸的基礎保障?

1. 編號機制:給每一個字節 “貼標簽”,實現按序重組

TCP 是 “面向字節流” 的協議(應用層發送的是字節流,而非獨立報文),為了讓接收方能夠識別數據的順序和完整性,TCP 會給每一個字節分配唯一的編號(序號)。

  • 具體規則:發送方發送的每個報文段的 “序號” 字段,是該報文段中第一個字節的編號。例如,若發送方已發送到字節 100,下一個報文段包含字節 101-200,則該報文段的序號為 101。
  • 作用:接收方通過序號判斷數據的先后順序,即使報文段因網絡延遲亂序到達,也能通過序號重新排序;同時,序號能幫助接收方識別重復數據(如因重傳導致的重復報文段)并丟棄。

2. 確認機制:接收方 “回信”,告知發送方 “已收到”

為了讓發送方知道數據是否被正確接收,TCP 采用 “確認(ACK)機制”:接收方收到數據后,會發送一個 “確認報文段”(ACK 報文),告知發送方 “哪些數據已正確接收”。

  • 確認號規則:ACK 報文的 “確認號” 字段,是接收方期望收到的下一個字節的編號。例如,若接收方已正確收到字節 1-100,則確認號為 101(表示 “我已收到 100 及之前的所有數據,下次請發 101 開始的字節”)。
  • 累積確認:TCP 默認使用 “累積確認”(Cumulative ACK),即只要連續收到數據,就只需要確認最后一個連續字節的下一個序號,無需對每個報文段單獨確認,減少 ACK 報文數量,提高效率。
  • 補充:若接收方收到不連續的數據(如丟失中間報文段),會發送 “重復 ACK”(確認號不變),觸發發送方快速重傳(見下文 “重傳機制”)。

3. 重傳機制:數據丟失?“補送” 一次

當數據或確認報文(ACK)因網絡故障丟失時,發送方需要重新發送數據,這一過程由 “重傳機制” 實現。重傳的觸發有兩種常見場景:

  • 超時重傳:若發送方在 “重傳定時器” 到期前未收到 ACK(假設數據或 ACK 丟失),則重傳該報文段。
  • 快速重傳:若發送方收到3 個連續的重復 ACK(表示接收方收到了亂序數據,且中間有數據丟失),則無需等待超時,立即重傳丟失的報文段(減少重傳延遲)。

4. 校驗機制:過濾 “損壞” 的數據,確保無差錯

TCP 通過 “校驗和” 驗證數據在傳輸過程中是否被損壞(如比特錯誤、篡改),是 “無差錯傳輸” 的核心保障。

  • 計算方式:發送方在發送前,對 TCP 報文段的 “首部 + 數據 + 偽首部”(偽首部包含源 IP、目的 IP 等,確保端到端正確性)計算校驗和,并填入 TCP 首部的 “校驗和” 字段;
  • 驗證方式:接收方收到報文段后,重新計算校驗和,若與首部的校驗和不一致,說明數據損壞,會直接丟棄該報文段(不發送 ACK),導致發送方重傳。

二、三類算法:優化傳輸效率,平衡速度與穩定性

四大機制確保了 “可靠性”,但單純依賴機制可能導致傳輸效率低下(如發送方等待每個 ACK 后再發下一個數據)。三類算法通過動態調整發送速率,在可靠的基礎上提升效率,同時避免 “過載”。

1. 滑動窗口算法:批量傳輸的 “效率引擎”

滑動窗口是 TCP 實現 “批量傳輸” 和 “動態控制” 的基礎,其核心是通過 “窗口大小” 限制發送方的發送范圍,實現 “無需等待每個 ACK 即可連續發送”。

  • 窗口定義:發送方的 “發送窗口” 是當前可發送數據的范圍(由序號標識),窗口內的字節可以連續發送,無需等待逐個確認;窗口外的字節需等待窗口滑動后才能發送。
  • 窗口滑動:當發送方收到 ACK 時,發送窗口會 “向前滑動”(窗口左邊界右移),新的字節進入窗口,可被發送。例如,發送窗口初始范圍是 1-100,收到確認號 101 的 ACK 后,窗口滑動為 101-200。
  • 作用:結合編號和確認機制,實現 “流水線式” 傳輸,大幅提升傳輸效率(避免 “停 - 等” 模式的低效)。

2. 流量控制算法:防止 “接收方被撐爆”

流量控制的目標是避免發送方發送過快,導致接收方緩沖區溢出(接收方處理速度跟不上發送速度)。其核心是接收方通過 “窗口字段” 告知發送方自己的接收能力。

  • 原理:接收方在 TCP 首部的 “窗口” 字段(接收窗口,rwnd)中,告知發送方自己當前的緩沖區剩余容量(即最多還能接收多少字節);發送方的 “發送窗口大小” 不能超過 rwnd(確保接收方來得及處理)。
  • 特殊場景:若接收方緩沖區滿了(rwnd=0),發送方會暫停發送;待接收方處理完數據、緩沖區有空閑后,會發送 “窗口更新報文”(rwnd>0),發送方恢復發送。

3. 擁塞控制算法:防止 “網絡被堵死”

擁塞控制的目標是避免發送方發送過快,導致網絡擁塞(如路由器緩沖區溢出、丟包)。其核心是通過 “擁塞窗口(cwnd)” 動態調整發送速率,cwnd 的大小由網絡狀況決定。

  • 核心邏輯:發送方的實際發送窗口大小 = min(接收窗口 rwnd,擁塞窗口 cwnd),既受接收方能力限制,也受網絡擁塞狀況限制。
  • 關鍵階段:
    • 慢啟動:連接初始時,cwnd 從 1 個報文段開始,每收到一個 ACK 就翻倍(指數增長),快速提升速率至 “擁塞閾值(ssthresh)”;
    • 擁塞避免:當 cwnd 超過 ssthresh 后,每輪 RTT(往返時間)cwnd 只增加 1 個報文段(線性增長),避免網絡擁塞;
    • 快速重傳與恢復:若收到 3 個重復 ACK(表示輕微擁塞),則立即重傳丟失報文,同時將 ssthresh 設為當前 cwnd 的一半,cwnd 設為 ssthresh(快速恢復,避免驟降);
    • 超時重傳:若超時(表示嚴重擁塞),則將 ssthresh 設為當前 cwnd 的一半,cwnd 重置為 1,重新進入慢啟動。

三、兩套定時器:解決 “超時” 和 “死鎖” 問題

定時器是 TCP 處理異常場景的 “保險裝置”,確保在數據丟失、窗口凍結等情況下,傳輸仍能正常推進。

1. 重傳定時器:檢測 “數據或 ACK 丟失”,觸發重傳

  • 作用:當發送方發送一個報文段后,立即啟動重傳定時器;若在定時器到期前收到對應的 ACK,則關閉定時器;若未收到,則判定數據或 ACK 丟失,觸發重傳。
  • 超時時間(RTO):RTO 并非固定值,而是基于 “往返時間(RTT,數據發送到收到 ACK 的時間)” 動態計算(如使用加權平均 RTT 和偏差值),確保 RTO 既能及時檢測丟失,又不會因網絡延遲誤判(避免頻繁無效重傳)。

2. 持續定時器:解決 “窗口為 0 導致的死鎖”

  • 場景:當接收方緩沖區滿(rwnd=0)時,發送方會停止發送數據;若后續接收方處理完數據,發送 “窗口更新報文(rwnd>0)” 但該報文丟失,發送方會一直等待,形成 “死鎖”。
  • 作用:當接收方告知 rwnd=0 時,發送方啟動持續定時器;定時器到期后,發送方發送一個 “窗口探查報文”(1 字節數據),接收方收到后會回復當前的 rwnd(無論是否為 0),若 rwnd>0,發送方恢復發送,打破死鎖。
機制作用關鍵點
序列號 / 確認號字節編號 + 累積確認每個字節都有序號(seq);ack = 期望收到的下一個字節號
重傳丟包恢復超時重傳(RTO)、快速重傳(3 個重復 ACK)
校驗和差錯檢測首部和數據一起反碼求和;出錯即丟棄
窗口批量確認允許連續發多幀而不必每幀都等 ACK,提高吞吐
算法控制對象典型策略
滑動窗口(Sliding Window)接收方緩存接收窗口?rwnd?告訴發送方“我還能收多少”
流量控制(Flow Control)端到端速率根據?rwnd?調整發送窗口,避免撐爆接收緩存
擁塞控制(Congestion Control)網絡擁塞慢啟動、擁塞避免、快重傳、快恢復,用?cwnd?探測可用帶寬

發送窗口大小 = min(rwnd, cwnd)?

定時器觸發時機動作
重傳定時器每發一個未被確認的段RTO 內未收到 ACK → 重傳
持續定時器收到零窗口通告周期性探測,防止窗口死鎖
  • 編號確認:字節有序號,ack?指下一字節

  • 重傳機制:超時 & 快速重傳

  • 流量控制rwnd 防止接收端溢出

  • 擁塞控制cwnd 防止網絡崩潰

  • 校驗和:檢錯即丟

  • 定時器:超時重傳 + 零窗口探測

TCP 粘包

產生TCP粘包的原因:

發送方原因

  • Nagle 算法:Nagle 算法是 TCP 協議中的一種優化機制,其目的是減少網絡中微小分組的數量,提高網絡利用率。該算法規定,當發送方應用程序調用 send () 函數發送數據時,如果發送緩沖區中存在未被確認的字節,那么新的數據會被緩存起來,直到緩沖區中的數據被確認或者緩沖區被填滿,才會將數據發送出去。這樣一來,就可能導致多個小數據被合并成一個大的數據塊發送,進而產生粘包。
  • 發送緩沖區機制:發送方應用程序不斷調用 send () 函數發送數據時,這些數據會先被放入操作系統的發送緩沖區中。如果發送的數據量較小,且發送頻率較高,操作系統可能會將這些小數據組合在一起進行發送,從而造成粘包。

接收方原因

  • 接收緩沖區機制:接收方通過 recv () 函數從操作系統的接收緩沖區中讀取數據。當接收緩沖區中的數據量達到一定程度,或者應用程序調用 recv () 函數的頻率較低時,可能會一次性讀取到多個原本獨立的數據包,表現為粘包現象 。例如,接收方緩沖區一次可以容納 1024 字節數據,而發送方先后發送了兩個 512 字節的數據包,接收方在讀取時可能就將這兩個數據包當作一個整體讀取,造成粘包。

解決方法

  • 消息定長法規定每個數據包的長度固定,接收方每次從接收緩沖區中讀取固定長度的數據作為一個完整的數據包。不過,這種方法在消息較短時會造成一定的空間浪費。
  • 包頭包體法在每個數據包前加上一個包頭,包頭中包含該數據包的長度等信息,包體則是實際的數據內容。接收方先讀取包頭,獲取數據包的長度,再根據長度讀取對應的包體數據。
  • 特殊分隔符法在數據包之間添加特殊的分隔符,接收方通過查找分隔符來確定數據包的邊界。增加了實現的復雜性。

使用套接字Socket常用函數(Linux系統為例)

套接字(Socket)是網絡編程中用于實現不同主機或同一主機上不同進程間網絡通信的抽象接口,是操作系統提供的一種進程間通信機制,本質上是內核中的一個數據結構,用于管理網絡連接和數據傳輸。

套接字是連接網絡應用程序與底層協議的橋梁,它隱藏了網絡傳輸的復雜細節,讓開發者能更簡單地實現進程間的網絡通信。

編程接口角度
套接字是應用程序與操作系統內核網絡協議棧之間的接口。開發者通過調用socket()等系統函數創建套接字,再通過bind()connect()send()recv()等函數操作它,實現數據的發送和接收,無需直接處理復雜的底層協議(如 TCP 握手、IP 路由等)。

通信端點角度
套接字可視為網絡通信的 “端點”。一次網絡通信需要兩個端點(如客戶端和服務端各有一個套接字),數據通過這兩個端點在網絡中流轉。每個端點由 “IP 地址 + 端口號” 標識,再結合協議類型(如 TCP/UDP),構成唯一的 “五元組”,確保數據能準確送達目標進程。

操作系統抽象角度
在 Unix/Linux 系統中,套接字被抽象為 “文件描述符”(類似文件、管道的標識),遵循 “一切皆文件” 的設計哲學。這意味著可以用操作文件的方式(如read()write()close())來操作套接字,簡化了網絡編程模型。

協議關聯角度
套接字與具體的網絡協議綁定,創建時需指定協議族(如 IPv4 的AF_INET)、套接字類型(如 TCP 的SOCK_STREAM、UDP 的SOCK_DGRAM)等,決定了通信的規則(如是否可靠、是否面向連接)。

socket() creates an endpoint for communication and returns a file descriptor that refers to that endpoint. The file descriptor returned by a successful call will be the lowest-numbered file descriptor not currently open for the process.

socket () 函數創建一個通信端點,并返回一個引用該端點的文件描述符。成功調用后返回的文件描述符,將是當前進程中未打開的編號最小的文件描述符。

RETURN VALUE
On success, a file descriptor for the new socket is returned. ?On error, -1 is returned, and errno is set appropriately.

成功時,返回新套接字的文件描述符。失敗時,返回 -1,并適當設置 errno(錯誤碼)。

#include <sys/socket.h>
int socket(int domain, int type, int protocol);說明:
domain:指定網絡協議族(如 AF_INET 對應 IPv4,AF_INET6 對應 IPv6 ),決定 “用什么網絡體系通信”;
type:指定套接字類型(如 SOCK_STREAM 對應 TCP 流式套接字,SOCK_DGRAM 對應 UDP 數據報套接字 ),決定 “通信的傳輸模式”;
protocol:一般填 0,讓系統自動匹配 domain + type 對應的默認協議(如 AF_INET + SOCK_STREAM 自動選 IPPROTO_TCP )。

調用后,系統會在內核中?創建一個套接字對象,并返回一個整數 “套接字描述符”(類似文件描述符)。后續所有網絡操作(綁定、連接、收發數據),都通過這個描述符操作 “內核里的套接字對象”,是網絡編程的第一步。?

套接字的完整標識是?“五元組”:{ 源IP, 源端口, 目的IP, 目的端口, 協議 }

服務端調用?bind()?時,會綁定?(源IP, 源端口, 協議)

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);struct sockaddr{sa_family_t sa_family;char        sa_data[14];
}
struct sockaddr_in {sa_family_t    sin_family; /* address family: AF_INET */in_port_t      sin_port;   /* port in network byte order */struct in_addr sin_addr;   /* internet address */
};
sockfd:通過 socket() 函數創建的套接字文件描述符,即需要被綁定的套接字。
addr:const struct sockaddr *(通常需要強轉為特定協議的地址結構,如 struct sockaddr_in 用于 IPv4)指向包含 “要綁定的 IP 地址和端口號” 的地址結構指針。以 IPv4 為例,實際使用的是 struct sockaddr_in 結構(需強制轉換為 struct sockaddr * 類型傳入)
addrlen:addr 指向的地址結構的大小(字節數),通常用 sizeof(struct sockaddr_in) 獲取。

客戶端調用?connect()?時,會指定?(目的 IP, 目的端口, 協議)

#include <sys/types.h>          /* See NOTES *
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
connect () 系統調用將文件描述符 sockfd 所指向的套接字,連接到 addr 所指定的地址。addrlen 參數指定了 addr 的大小。addr 中地址的格式由套接字 sockfd 的地址空間決定
RETURN VALUEIf the connection or binding succeeds, zero is returned.  On error, -1 is returned, and errno is set appropriately.

監聽 listen()

將?sockfd?標識的套接字轉換為監聽套接字(進入?LISTEN?狀態),使其具備接收客戶端?connect()?請求的能力。listen () 函數將 sockfd 所指向的套接字標記為被動套接字,即該套接字將用于通過 accept () 函數接收傳入的連接請求。

  • 被動套接字(passive socket):服務端特有的套接字狀態,與客戶端的 “主動套接字”(發起連接)相對。被動套接字的唯一作用是監聽并接收客戶端的連接請求,不直接參與數據傳輸。
  • 與 accept (2) 的關聯:被 listen () 標記為被動的套接字,必須配合 accept () 使用 ——accept () 會從該套接字的連接隊列中取出已完成的連接,創建新的套接字用于實際的數據收發(監聽套接字本身仍繼續接收新請求)。
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int listen(int sockfd, int backlog);
backlog:指定未完成連接隊列(處于 SYN_RCVD 狀態)和已完成連接隊列(處于 ESTABLISHED 狀態)的總長度上限。
未完成連接:客戶端發送 SYN 后,三次握手未完成的連接
已完成連接:三次握手完成,等待服務端調用 accept() 接收的連接
實際值:系統會根據內核參數(如 net.core.somaxconn)對 backlog 進行限制,通常取 5 到 128(高并發場景可能更大)

發送 send()?

send () 調用僅能在套接字處于已連接狀態時使用(此時目標接收方是已知的)。send () 與 write (2) 的唯一區別在于是否存在 flags 參數。當 flags 參數為 0 時,send () 與 write (2) 功能等價。

#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
flags:發送選項標志,通常設為 0(默認行為)
常用標志包括:
MSG_OOB:發送帶外數據(用于 TCP 緊急數據傳輸)
MSG_DONTWAIT:非阻塞發送(即使緩沖區滿也不阻塞,立即返回)
MSG_NOSIGNAL:發送失敗時不產生 SIGPIPE 信號(避免進程被終止)

接受收recv()

從?sockfd?標識的套接字接收數據,并將數據存入?buf?緩沖區,最多接收?len?字節。

#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
flags:接收選項標志,通常設為 0(默認行為)。
常用標志包括:
MSG_OOB:接收帶外數據(TCP 緊急數據)
MSG_PEEK:預覽數據(讀取數據但不從內核緩沖區移除,可用于查看數據而不消費)
MSG_WAITALL:阻塞等待直到接收滿 len 字節(或發生錯誤 / 連接關閉)
MSG_DONTWAIT:非阻塞接收(無數據時立即返回,不阻塞)

結語:

無論你是初學者還是有經驗的開發者,我希望我的博客能對你的學習之路有所幫助。如果你覺得這篇文章有用,不妨點擊收藏,或者留下你的評論分享你的見解和經驗,也歡迎你對我博客的內容提出建議和問題。每一次的點贊、評論、分享和關注都是對我的最大支持,也是對我持續分享和創作的動力

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/92408.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/92408.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/92408.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

K 近鄰算法(K-Nearest Neighbors, KNN)詳解及案例

K近鄰算法&#xff08;K-Nearest Neighbors, KNN&#xff09;詳解及案例 一、基本原理 K近鄰算法是一種監督學習算法&#xff0c;核心思想是“物以類聚&#xff0c;人以群分”&#xff1a;對于一個新樣本&#xff0c;通過計算它與訓練集中所有樣本的“距離”&#xff0c;找出距…

深入理解 Redis 集群化看門狗機制:原理、實踐與風險

在分布式系統中&#xff0c;我們常常需要執行一些關鍵任務&#xff0c;這些任務要么必須成功執行&#xff0c;要么失敗后需要明確的狀態&#xff08;如回滾&#xff09;&#xff0c;并且它們的執行時間可能難以精確預測。如何確保這些任務不會被意外中斷&#xff0c;或者在長時…

Python機器學習:從零基礎到項目實戰

目錄第一部分&#xff1a;思想與基石——萬法歸宗&#xff0c;筑基問道第1章&#xff1a;初探智慧之境——機器學習世界觀1.1 何為學習&#xff1f;從人類學習到機器智能1.2 機器學習的“前世今生”&#xff1a;一部思想與技術的演進史1.3 為何是Python&#xff1f;——數據科學…

數據庫:庫的操作

1&#xff1a;查看所有數據庫SHOW DATABASES;2&#xff1a;創建數據庫CREATE DATABASE [ IF NOT EXISTS ] 數據庫名 [ CHARACTER SET 字符集編碼 | COLLATE 字符集校驗規則 | ENCRYPTION { Y | N } ];[]&#xff1a;可寫可不寫{}&#xff1a;必選一個|&#xff1a;n 選 1ENCR…

AngularJS 動畫

AngularJS 動畫 引言 AngularJS 是一個流行的JavaScript框架,它為開發者提供了一種構建動態Web應用的方式。在AngularJS中,動畫是一個強大的功能,可以幫助我們創建出更加生動和引人注目的用戶界面。本文將詳細介紹AngularJS動畫的原理、用法以及最佳實踐。 AngularJS 動畫…

SonarQube 代碼分析工具

??親愛的技術愛好者們,熱烈歡迎來到 Kant2048 的博客!我是 Thomas Kant,很開心能在CSDN上與你們相遇~?? 本博客的精華專欄: 【自動化測試】 【測試經驗】 【人工智能】 【Python】 ??全面掌握 SonarQube:企業代碼質量保障的利器 ?? 在當今 DevOps 流水線中,代碼…

vmware vsphere esxi6.5 使用工具導出鏡像

注&#xff1a;為什么使用這個工具&#xff0c;我這邊主要因為esxi6.5自身bug導致web導出鏡像會失敗一、下載VMware-ovftool到本地系統&#xff08;根據你的操作系統版本到官網下載安裝&#xff0c;此處略&#xff09;以下內容默認將VMware-ovftool安裝到windows 本地系統為例。…

ES 踩坑記:Set Processor 字段更新引發的 _source 污染

問題背景 社區的一個伙伴想對一個 integer 的字段類型添加一個 keyword 類型的子字段&#xff0c;然后進行精確匹配的查詢優化&#xff0c;提高查詢的速度。 整個索引數據量不大&#xff0c;并不想進行 reindex 這樣的復雜操作&#xff0c;就想到了使用 update_by_query 的存量…

如何徹底搞定 PyCharm 中 pip install 報錯 ModuleNotFoundError: No module named ‘requests’ 的問題

如何徹底搞定 PyCharm 中 pip install 報錯 ModuleNotFoundError: No module named ‘requests’ 的問題 在使用 PyCharm 開發 Python 項目時&#xff0c;ModuleNotFoundError: No module named requests 是一個常見但令人頭疼的問題。本篇博文將從環境配置、原因分析到多種解…

powerquery如何實現表的拼接主鍵

在做表過程中&#xff0c;有時候沒有基表&#xff0c;這個時候就要構造完整的主鍵&#xff0c;這樣才可以使之后匹配的數據不會因為主鍵不全而丟失數據 我的處理方法是吧多個表的主鍵拼在一起然后去重&#xff0c;構造一個單單之后之間的表作為基表去匹配數據 所以就喲啊用到自…

今日Github熱門倉庫推薦 第八期

今日Github熱門倉庫推薦2025-07-22 如果讓AI分別扮演 后端開發人員和前端開發人員&#xff0c;然后看看他們分別對github每天的trending倉庫感興趣的有哪些&#xff0c;并且給出他感興趣的理由&#xff0c;那會發生什么呢&#xff1f; 本內容通過Python AI生成&#xff0c;項…

Dify-13: 文本生成API端點

本文檔提供了有關 Dify 中與文本生成相關的 API 端點的全面信息。文本生成 API 支持無會話持久性的單次請求文本生成&#xff0c;使其適用于翻譯、摘要、文章寫作等非對話式人工智能應用場景。 概述 文本生成 API 端點允許開發人員將 Dify 的文本生成功能集成到不需要維護對話上…

Leetcode 3620. Network Recovery Pathways

Leetcode 3620. Network Recovery Pathways 1. 解題思路2. 代碼實現 題目鏈接&#xff1a;3620. Network Recovery Pathways 1. 解題思路 這一題我最開始想的是遍歷一下所有的網絡路徑&#xff0c;不過遇到了超時的情況。因此后來調整了一下處理思路&#xff0c;使用二分法的…

鏈路備份技術(鏈路聚合、RSTP)

一、鏈路聚合&#xff01;鏈路備份技術之一-----鏈路聚合&#xff08;Link Aggregation&#xff09;被視為鏈路備份技術&#xff0c;核心原因在于它能通過多條物理鏈路的捆綁&#xff0c;實現 “一條鏈路故障時&#xff0c;其他鏈路自動接管流量” 的冗余備份效果&#xff0c;同…

PyTorch新手實操 安裝

PyTorch簡介 PyTorch 是一個基于 Python 的開源深度學習框架&#xff0c;由 Meta AI&#xff08;原 Facebook AI&#xff09;主導開發&#xff0c;以動態計算圖&#xff08;Define-by-Run&#xff09;為核心&#xff0c;支持靈活構建和訓練神經網絡模型。其設計理念高度契合科…

Element Plus Table 組件擴展:表尾合計功能詳解

前言在現代數據驅動的社會中&#xff0c;數據分析和統計成為了非常重要的任務。為了更有效地分析數據和展示統計結果&#xff0c;前端開發人員可以使用Vue框架和Element Plus組件庫來實現數據的統計和分析功能。以下是一個關于如何在 Element Plus 的 el-table 組件中實現行匯總…

神經網絡 非線性激活層 正則化層 線性層

神經網絡 非線性激活層 作用&#xff1a;增強模型的非線性擬合能力 非線性激活層網絡&#xff1a; class activateNet(nn.Module):def __init__(self):super(activateNet,self).__init__()self.relu nn.ReLU()self.sigmoid nn.Sigmoid()def forward(self,input):#output sel…

【Vue進階學習筆記】組件通信專題精講

目錄前言props 父傳子原理說明使用場景代碼示例父組件 PropsTest.vue子組件 Child.vue自定義事件 $emit 子傳父原理說明使用場景代碼示例父組件 EventTest.vue子組件 Event2.vueEvent Bus 兄弟/跨層通信原理說明使用場景代碼示例事件總線 bus/index.ts兄弟組件通信示例Child2.v…

【PTA數據結構 | C語言版】求最小生成樹的Prim算法

本專欄持續輸出數據結構題目集&#xff0c;歡迎訂閱。 文章目錄題目代碼題目 請編寫程序&#xff0c;實現在帶權的無向圖中求最小生成樹的 Prim 算法。 注意&#xff1a;當多個待收錄頂點到當前點集的距離等長時&#xff0c;按編號升序進行收錄。 輸入格式&#xff1a; 輸入首…

【加解密與C】Rot系列(四)RotSpecial

RotSpecial 函數解析RotSpecial 是一個自定義函數&#xff0c;通常用于處理特定的旋轉操作&#xff0c;尤其在圖形變換或數據處理中。該函數可能涉及歐拉角、四元數或其他旋轉表示方法&#xff0c;具體行為取決于實現上下文。以下是關于該函數的通用解釋和可能的使用方法&#…