Socket some functions

setsockopt 簡介

setsockopt 是用于設置套接字(socket)選項的系統調用函數,允許用戶對套接字的行為進行精細控制。通過調整選項參數,可以優化網絡通信性能、修改超時設置、啟用特殊功能等。該函數在 POSIX 系統和 Windows 平臺均有支持,但部分選項可能因操作系統而異。

函數原型

int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

  • sockfd:目標套接字的文件描述符。
  • level:選項的協議層級(如 SOL_SOCKETIPPROTO_TCP)。
  • optname:具體選項名稱(如 SO_REUSEADDRTCP_NODELAY)。
  • optval:指向選項值的指針,類型取決于選項。
  • optlen:選項值的長度。

常用選項及用法

地址復用(SO_REUSEADDR)

允許綁定到處于 TIME_WAIT 狀態的地址,適用于服務器快速重啟。

int reuse = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));

禁用 Nagle 算法(TCP_NODELAY)

減少小數據包的延遲,適用于實時性要求高的場景。

int nodelay = 1;
setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay));

設置接收超時(SO_RCVTIMEO)

指定套接字接收數據的超時時間。

struct timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));

錯誤處理

函數返回值為 0 表示成功,-1 表示失敗,可通過 errno 獲取具體錯誤原因。例如:

if (setsockopt(sockfd, SOL_SOCKET, optname, &value, sizeof(value)) == -1) {perror("setsockopt failed");exit(EXIT_FAILURE);
}

注意事項

  • 不同操作系統支持的選項可能不同,需查閱文檔確認兼容性。
  • 部分選項需在特定時機設置(如綁定前或連接前)。
  • 選項值的類型和含義需嚴格匹配,否則可能導致未定義行為。

SO_REUSEPORT 概述

SO_REUSEPORT 是一個套接字選項,允許多個套接字綁定到相同的 IP 地址和端口組合。該特性最初在 Linux 3.9 內核中引入,旨在提高多核系統的網絡性能,尤其是在高并發場景下。通過允許多個進程或線程同時監聽同一端口,可以更高效地分配連接負載。

工作原理

當啟用 SO_REUSEPORT 時,內核會使用哈希算法將傳入的連接請求均勻分配到所有綁定到同一地址和端口的套接字上。這種方式避免了傳統的單一監聽套接字可能成為性能瓶頸的問題。哈希算法通常基于源 IP 地址、源端口和目標 IP 地址的組合,確保同一客戶端連接始終被分配到同一套接字。

使用方法

在 Linux 系統中,可以通過 setsockopt 函數設置 SO_REUSEPORT 選項。以下是一個簡單的 C 代碼示例:

int sockfd = socket(AF_INET, SOCK_STREAM, 0);
int optval = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));

適用場景

  • 負載均衡:多個進程或線程可以同時監聽同一端口,內核自動分配連接請求。
  • 無縫重啟:新啟動的服務實例可以綁定到同一端口,而舊實例仍在處理連接,實現零停機重啟。
  • 多協議支持:不同協議的服務可以綁定到同一端口,例如 TCP 和 UDP 服務。

注意事項

  • 內核版本要求:SO_REUSEPORT 需要 Linux 3.9 或更高版本的支持。
  • 權限問題:所有綁定到同一端口的套接字必須具有相同的有效用戶 ID,防止權限濫用。
  • 連接分配:哈希算法可能導致連接分配不均勻,尤其是在客戶端數量較少時。

與 SO_REUSEADDR 的區別

SO_REUSEADDR 是另一個套接字選項,主要用于解決端口占用問題,例如在服務重啟時快速重用端口。兩者的主要區別在于:

  • SO_REUSEADDR 允許多個套接字綁定到同一地址和端口,但只有一個套接字可以處于監聽狀態。
  • SO_REUSEPORT 允許多個套接字同時監聽同一地址和端口,內核負責連接分配。

性能優勢

在高并發場景下,SO_REUSEPORT 可以顯著提升性能:

  • 減少鎖競爭:傳統單一監聽套接字可能導致多核系統上的鎖競爭。
  • 更好的 CPU 親和性:連接請求被分配到不同的套接字,可以更好地利用多核 CPU。

示例:多進程服務器

以下是一個使用 SO_REUSEPORT 的多進程服務器示例:

#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>int main() {int sockfd = socket(AF_INET, SOCK_STREAM, 0);int optval = 1;setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(8080);addr.sin_addr.s_addr = INADDR_ANY;bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));listen(sockfd, 10);for (int i = 0; i < 4; ++i) {if (fork() == 0) {while (1) {int client_fd = accept(sockfd, NULL, NULL);printf("Process %d handling connection\n", getpid());close(client_fd);}}}pause();return 0;
}

限制與挑戰

  • 連接分配不均:哈希算法可能導致某些進程或線程處理更多連接。
  • 調試復雜性:多監聽套接字可能增加調試難度,尤其是在連接分配異常時。
  • 兼容性問題:某些舊版操作系統或網絡設備可能不支持 SO_REUSEPORT。

TCP_NODELAY 概述

TCP_NODELAY 是 TCP 協議的一個套接字選項(通過 setsockopt 設置),用于禁用 Nagle 算法。Nagle 算法旨在減少小數據包的傳輸,通過合并緩沖區中的小數據包并等待確認(ACK)后再發送,但會增加延遲。啟用 TCP_NODELAY 后,數據會立即發送,適合低延遲場景。


適用場景

  • 實時應用:如在線游戲、視頻會議、遠程桌面等對延遲敏感的場景。
  • 交互式協議:如 SSH、Telnet,用戶輸入需即時反饋。
  • 高頻交易系統:金融領域需最小化網絡延遲。

使用方法

在代碼中通過 setsockopt 啟用 TCP_NODELAY(以 C 為例):

int enable = 1;
setsockopt(socket_fd, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable));


與 Nagle 算法的關系

  • Nagle 算法:默認啟用,合并小數據包,提高帶寬利用率,但增加延遲。
  • TCP_NODELAY:禁用 Nagle 算法,犧牲帶寬效率換取低延遲。

注意事項

  • 帶寬影響:禁用 Nagle 可能導致小包增多,占用更多帶寬。
  • 與延遲確認(Delayed ACK)的交互:延遲確認機制可能加劇延遲問題,需結合調整。
  • 默認行為:多數系統默認啟用 Nagle,需顯式設置 TCP_NODELAY 關閉。

替代方案

  • TCP_QUICKACK:臨時禁用延遲確認,適合單次低延遲需求(需每次接收后重置)。
  • 應用層緩沖:手動合并數據包,平衡延遲與效率。

代碼示例(Python)

import sockets = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)

Socket的Write、Read和Shutdown操作解釋

在網絡編程中,Socket是用于進程間通信(如TCP/IP協議)的基礎工具。writeread操作用于數據傳輸,而shutdown操作用于優雅地關閉部分連接。結構如下:

  1. Socket的Write操作:發送數據。
  2. Socket的Read操作:接收數據。
  3. Shutdown操作:特別是關閉寫入端(SHUT_WR)。
  4. 整體作用與示例:為什么需要這些操作,并給出Python代碼演示。

1. Socket的Write操作(發送數據)
  • write操作(或send)用于將數據從應用程序發送到網絡。
  • 在TCP Socket中,它保證數據的可靠傳輸(基于TCP的可靠性)。
  • 例如,在客戶端發送請求時使用:
    • 函數形式:socket.write(data)socket.send(data)
    • 數據可以是字節序列,如字符串編碼后的結果。
    • 如果發送失敗,會返回錯誤(如連接中斷)。
2. Socket的Read操作(接收數據)
  • read操作(或recv)用于從網絡接收數據到應用程序。
  • 它讀取對方發送的數據,并返回字節流。
  • 例如,在服務器接收請求時使用:
    • 函數形式:data = socket.read(buffer_size)data = socket.recv(buffer_size)
    • buffer_size指定最大讀取字節數。
    • 如果連接關閉或出錯,返回空數據或錯誤。
3. Shutdown操作(關閉寫入端:SHUT_WR
  • shutdown操作用于部分關閉Socket,而不完全關閉連接。
  • 關鍵參數:
    • SHUT_WR:關閉寫入端(write side),表示本端不再發送數據,但可以繼續接收數據。
    • 其他選項:SHUT_RD(關閉讀取端)或SHUT_RDWR(關閉讀寫兩端)。
  • 為什么需要shutdown(SHUT_WR)
    • 在TCP通信中,一方完成數據發送后,調用shutdown(SHUT_WR)通知對方“不會再發送新數據”。
    • 對方可以通過read操作檢測到EOF(文件結束符),從而知道數據已完整接收。
    • 這避免了“半關閉”狀態問題:例如,如果直接關閉Socket,對方可能無法優雅結束接收。
    • 典型場景:客戶端發送完請求后關閉寫入端,服務器接收完數據后關閉連接。
  • 函數形式:socket.shutdown(how),其中how指定關閉方式(如socket.SHUT_WR)。
4. 整體作用與示例
  • 作用總結
    • writeread實現雙向數據傳輸。
    • shutdown(SHUT_WR)用于優雅終止發送端,確保數據完整性,常用于協議如HTTP(客戶端發送請求后關閉寫入)。
    • 這比直接close()更安全,因為它允許對方完成接收。
  • Python代碼示例
    • 以下是一個簡單的TCP客戶端和服務器演示,展示writereadshutdown(SHUT_WR)的使用。
    • 服務器接收數據后,檢測EOF并回復。
# 服務器端代碼(接收數據,檢測寫入端關閉)
import socketdef run_server():server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server_socket.bind(('localhost', 8080))server_socket.listen(1)print("服務器啟動,等待連接...")client_socket, addr = server_socket.accept()print(f"連接來自: {addr}")# 循環讀取數據,直到檢測到EOF(對方關閉寫入端)data = b''while True:chunk = client_socket.recv(1024)  # read操作if not chunk:break  # 檢測到EOF,跳出循環data += chunkprint(f"接收數據: {data.decode()}")client_socket.send(b"ACK: 數據已接收")  # write操作回復client_socket.close()server_socket.close()if __name__ == '__main__':run_server()

# 客戶端代碼(發送數據后關閉寫入端)
import socketdef run_client():client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client_socket.connect(('localhost', 8080))# 發送數據(write操作)client_socket.send(b"Hello, Server! This is a test message.")# 關閉寫入端(shutdown SHUT_WR),通知服務器不再發送數據client_socket.shutdown(socket.SHUT_WR)  # 關鍵步驟# 繼續讀取服務器回復response = client_socket.recv(1024)  # read操作print(f"服務器回復: {response.decode()}")client_socket.close()if __name__ == '__main__':run_client()

  • 示例說明
    • 客戶端發送數據后調用shutdown(SHUT_WR),服務器通過recv返回空數據檢測EOF。
    • 這確保了服務器知道數據已完整,并發送回復。
    • 如果沒有shutdown,服務器可能無限等待數據,導致資源浪費。

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

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

相關文章

玩轉深度學習數據填補!CNN-GRU組合模型數據填補(四個案例數據)

這兩段MATLAB代碼&#xff08;BABJ.m 和 CNN_GRUQSTB.m&#xff09;分別完成數據預處理與缺失值標識和基于CNN-GRU混合神經網絡的缺失值預測填補任務。以下是詳細分析&#xff1a; 一、主要功能 BABJ.m ? 功能&#xff1a;從多個Excel文件中讀取數據&#xff0c;匹配并合并多個…

基于開源AI智能名片鏈動2+1模式S2B2C商城小程序的營銷創新研究——以“種草”實踐踐行“以人為本”理念

摘要&#xff1a;本文聚焦于營銷本質&#xff0c;強調創造和維護與消費者有價值關系的重要性&#xff0c;指出企業需回歸消費者視角提供有價值產品和服務。深入探討“種草”作為科特勒“以人為本”理念在中國市場的最佳實踐&#xff0c;分析其意義與價值。同時&#xff0c;引入…

基于SpringBoot+Vue的智能停車場管理系統 停車管理小程序

&#x1f525;作者&#xff1a;it畢設實戰小研&#x1f525; &#x1f496;簡介&#xff1a;java、微信小程序、安卓&#xff1b;定制開發&#xff0c;遠程調試 代碼講解&#xff0c;文檔指導&#xff0c;ppt制作&#x1f496; 精彩專欄推薦訂閱&#xff1a;在下方專欄&#x1…

01數據結構-歸并排序和計數排序

01數據結構-歸并排序和計數排序1.歸并排序1.1歸并排序概述1.2歸并排序的執行流程1.2.1遞(分裂)的過程1.2.2歸(合并)的過程1.3歸并排序的代碼實現2.計數排序2.1算法思想2.2計數排序的改進2.2.1優化12.2.2優化21.歸并排序 1.1歸并排序概述 歸并排序&#xff0c;其排序的實現思想…

SQL注入2----(sql注入數據類型分類)

一.前言本章節我們來講解一下sql注入的分類&#xff0c;主要分為四類&#xff0c;數字型、字符型、搜索型、xx型。二.數字型數字型注入的時候&#xff0c;是不需要考慮單\雙引號閉合問題的&#xff0c;因為sql語句中的數字是不需要用引號括起來的&#xff0c;如下mysql> sel…

Elasticsearch Rails 實戰全指南(elasticsearch-rails / elasticsearch-model)

一、背景與生態總覽 elasticsearch-rails&#xff1a;面向 Rails 的“伴生庫”&#xff0c;為 Rails 項目帶來 Rake 任務、日志埋點、模板等特性。elasticsearch-model&#xff1a;把 ES 能力“混入”到 Ruby 模型&#xff08;ActiveRecord/Mongoid&#xff09;&#xff0c;提供…

第三階段數據庫-2:數據庫中的sql語句

1_數據庫操作&#xff08;1&#xff09;注釋&#xff1a;-- 單行注釋 /**/ 多行注釋&#xff08;2&#xff09;創建數據庫&#xff1a;create database 數據庫名-- create database 數據庫名 create database db_first;(3&#xff09;查詢數據庫&#xff1a;if exsists(select…

python中的filter函數

目錄 定義與參數說明 特點 使用場景 常用操作 篩選偶數 去除空字符串 篩選正數 篩選字典 配合集合與元組 注意事項 定義與參數說明 filter函數是Python內置的高階函數之一&#xff0c;用于篩選可迭代對象中的元素&#xff0c;根據返回值的布爾結果&#xff08;True 或…

BERT(Bidirectional Encoder Representations from Transformers)模型詳解

一、BERT 簡介BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;是由 Google 在 2018 年提出的一種預訓練語言表示模型。它基于 Transformer 編碼器結構&#xff0c;首次提出了 雙向上下文建模 的方法&#xff0c;大幅度提升了自然語言處理…

【開題答辯全過程】以 基于Springboot+微信小程序的網上家教預約系統的設計與實現-開題為例,包含答辯的問題和答案

個人簡介&#xff1a;一名14年經驗的資深畢設內行人&#xff0c;語言擅長Java、php、微信小程序、Python、Golang、安卓Android等開發項目包括大數據、深度學習、網站、小程序、安卓、算法。平常會做一些項目定制化開發、代碼講解、答辯教學、文檔編寫、也懂一些降重方面的技巧…

課小悅系列智能耳機上市,用硬核科技為教育賦能

在人工智能與教育深度融合的浪潮中&#xff0c;深圳課小悅科技有限公司以“智慧教育專家”的姿態嶄露頭角。這家深耕智能教育硬件的創新企業&#xff0c;于2025年8月正式推出革命性產品H360PRO系列教考耳機&#xff0c;為語言學習場景提供顛覆性解決方案。創新基因&#xff1a;…

[react] class Component and function Component

我對react的用法理解還一直停留在多年以前&#xff0c;說明這段時間我沒有更新react的知識。我大腦中記得還是使用Class Component this.setState&#xff0c;可是今天看了看react的文檔&#xff0c;發現怎么不一樣了&#xff0c;用的都是function useState的方式了。你知道這…

以太坊智能合約地址派生方式:EOA、CREATE 和 CREATE2

1. 引言 在以太坊上&#xff0c;智能合約可以通過以下三種方式之一進行部署&#xff1a; 1&#xff09;由外部賬戶&#xff08;Externally Owned Account, EOA&#xff09;發起交易&#xff0c;其中 to 字段設為 null&#xff0c;而 data 字段包含合約的初始化代碼。2&#x…

基于RISC-V架構的國產MCU在eVTOL領域的應用研究與挑戰分析

摘要電動垂直起降飛行器&#xff08;eVTOL&#xff09;作為未來城市空中交通的重要組成部分&#xff0c;對嵌入式控制系統的性能、可靠性和安全性提出了極高的要求。RISC-V作為一種新興的開源指令集架構&#xff0c;為國產微控制器&#xff08;MCU&#xff09;的研發和應用帶來…

深度學習中的“集體智慧”:Dropout技術詳解——不僅是防止過擬合,更是模型集成的革命

引言&#xff1a;從“過擬合”的噩夢說起 在訓練深度學習模型時&#xff0c;我們最常遇到也最頭疼的問題就是過擬合&#xff08;Overfitting&#xff09;。 想象一下&#xff0c;你是一位正在備考的學生&#xff1a; 欠擬合&#xff1a;你根本沒學進去&#xff0c;所有題都做錯…

在JavaScript中,比較兩個數組是否有相同元素(交集)的常用方法

方法1&#xff1a;使用 some() includes()&#xff08;適合小數組&#xff09;function haveCommonElements(arr1, arr2) {return arr1.some(item > arr2.includes(item)); }// 使用示例 const arrA [1, 2, 3]; const arrB [3, 4, 5]; console.log(haveCommonElements(ar…

心路歷程-Linux的系統破解詳細解說

CentOS7系統密碼破解 密碼破解是分兩種情況的&#xff1b;一種是在系統的界面內&#xff0c;一種就是不在系統的頁面&#xff1b; 今天我們就來聊聊這個系統破解的話題&#xff1b; 1.為什么需要破解密碼&#xff1f;–>那當然是忘記了密碼&#xff1b;需從新設置密碼 2.但是…

IDE和AHCI硬盤模式有什么區別

IDE&#xff08;Integrated Drive Electronics&#xff09;和 AHCI&#xff08;Advanced Host Controller Interface&#xff09;是硬盤控制器的工作模式&#xff0c;主要區別在于性能、功能兼容性以及對現代存儲設備的支持程度。以下是詳細對比和分析&#xff1a;一、本質區別…

【密碼學實戰】密碼實現安全測試基礎篇 . KAT(已知答案測試)技術解析與實踐

KAT 測試技術解析 在密碼算法的安全性驗證體系中&#xff0c;Known Answer Test&#xff08;KAT&#xff0c;已知答案測試&#xff09;是一項基礎且關鍵的技術。它通過 “已知輸入 - 預期輸出” 的確定性驗證邏輯&#xff0c;為密碼算法實現的正確性、合規性提供核心保障&…

如何用Redis作為消息隊列

說明&#xff1a;以前背八股文&#xff0c;早就知道 Redis 可以作為消息隊列&#xff0c;本文介紹如何實現用 Redis 作為消息隊列。 介紹 這里直接介紹 yudao 框架中的實現。yudao 是一套現成的開源系統框架&#xff0c;里面集成了許多基礎功能&#xff0c;我們可以在這基礎上…