【Linux 學習指南】網絡編程基礎:從 IP、端口到 Socket 與 TCP/UDP 協議詳解

請添加圖片描述

文章目錄

  • 📝理解源IP地址和目的IP地址
  • 🌠 認識端口號
    • 🌉端口號范圍劃分
    • 🌉理解"端口號"和"進程ID"
    • 🌉理解源端口號和目的端口號
    • 🌉理解socket
  • 🌠傳輸層的典型代表
    • 🌉認識TCP協議
    • 🌉 認識UDP協議
  • 🌠網絡字節序
  • 🌠Socket 編程接口
    • 🌉Socket 常見API
    • 🌉sockaddr 結構
    • 🌉`in_addr` 結構
  • 🚩總結


📝理解源IP地址和目的IP地址

  • IP在網絡中,用來標識主機的唯一性
  • 注意:后面我們會講IP的分類,后面會詳細闡述IP的特點
    但是這里要思考一個問題:數據傳輸到主機是目的嗎?不是的。因為數據是給人用的。比如:聊天是人在聊天,下載是人在下載,瀏覽網頁是人在瀏覽?

但是人是怎么看到聊天信息的呢?怎么執行下載任務呢?怎么瀏覽網頁信息呢?通過啟動的qq,迅雷,瀏覽器。
而啟動的qq,迅雷,瀏覽器都是進程。換句話說,進程是人在系統中的代表,只要把數據給進程,人就相當于就拿到了數據。

所以:數據傳輸到主機不是目的,而是手段。到達主機內部,在交給主機內的進程,才是目的。

但是系統中,同時會存在非常多的進程,當數據到達目標主機之后,怎么轉發給目標進程?這就要在網絡的背景下,在系統中,標識主機的唯一性。

在這里插入圖片描述

🌠 認識端口號

端口號(port)是傳輸層協議的內容

  • 端口號是一個2字節16位的整數;
  • 端口號用來標識一個進程,告訴操作系統,當前的這個數據要交給哪一個進程來處理;
  • IP地址+端口號能夠標識網絡上的某一臺主機的某一個進程;
  • 一個端口號只能被一個進程占用.

在這里插入圖片描述

🌉端口號范圍劃分

  • 0-1023: 知名端口號,HTTP,FTP,SSH等這些廣為使用的應用層協議,他們的端口號都是固定的.
  • 1024-65535: 操作系統動態分配的端口號.客戶端程序的端口號,就是由操作系統從這個范圍分配的

🌉理解"端口號"和"進程ID"

我們之前在學習系統編程的時候,學習了pid表示唯一一個進程;此處我們的端口號也是唯一表示一個進程.那么這兩者之間是怎樣的關系?

在Linux系統中,進程ID(PID)和端口號都可用于標識進程,但二者有著不同的概念和用途,它們之間存在一定的關聯關系。具體如下:

  • 概念及用途不同
    • 進程ID(PID):是系統為每個運行中的進程分配的唯一標識符,屬于系統級的概念。無論進程是否參與網絡通信,系統都會為其分配PID,用于在內核中管理和區分各個進程,是操作系統進行進程調度、資源分配等操作的重要依據。
    • 端口號:是傳輸層協議的內容,是一個16位的整數,用于在網絡通信中標識主機中的進程。它是網絡概念,主要用于區分同一臺主機上不同的網絡服務或應用程序,當數據通過網絡傳輸到主機時,操作系統根據端口號將數據交給對應的進程處理。
  • 對應關系
    • 一個進程可以綁定多個端口號。例如,一個Web服務器進程可能同時監聽80端口(用于HTTP協議)和443端口(用于HTTPS協議),就像一個人可以有多個身份標識,在不同場景下使用不同標識一樣。
    • 一個端口號只能被一個進程占用(特殊情況除外,如支持多進程監聽的情況,但也是在特定機制下),以保證標識進程的唯一性,否則會導致網絡數據傳輸混亂。
  • 查詢方法
    • 已知PID查詢端口號,可以使用netstat -tulnp | grep <PID>lsof -i -P -n | grep <PID>命令。
    • 已知端口號查詢PID,可以使用netstat -nap | grep <端口號>lsof -i :<端口號>命令。

以10086為例,如果有一個進程號為10086的進程,你想知道它占用了哪些端口,可以使用sudo netstat -tulnp | grep 10086命令來查看。反之,如果已知某個網絡服務使用的端口號是10086,想知道是哪個進程在占用該端口,則可以使用sudo lsof -i :10086命令,命令執行后會顯示占用該端口的進程PID及相關信息。

因此:一個進程可以綁定多個端口號;但是一個端口號不能被多個進程綁定;

進程ID屬于系統概念,技術上也具有唯一性,確實可以用來標識唯一的一個進程,但是這樣做,會讓系統進程管理和網絡強耦合,實際設計的時候,并沒有選擇這樣做。

🌉理解源端口號和目的端口號

傳輸層協議(TCPUDP)的數據段中有兩個端口號,分別叫做源端口號和目的端口號.就是在描述"數據是誰發的,要發給誰"

🌉理解socket

綜上,IP地址用來標識互聯網中唯一的一臺主機,port用來標識該主機上唯一的
一個網絡進程
? IP+Port就能表示互聯網中唯一的一個進程
? 所以,通信的時候,本質是兩個互聯網進程代表人來進行通信,{srcIpsrcPortdstIpdstPort}這樣的 4元組就能標識互聯網中唯二的兩個進程
? 所以,網絡通信的本質,也是進程間通信
? 我們把ip+port叫做套接字socket

C++
socket
n.
(電源)插座;(電器上的)插口,插孔,管座;槽;窩;托座;臼;孔穴
vt.
把…裝入插座;給…配插座

🌠傳輸層的典型代表

如果我們了解了系統,也了解了網絡協議棧,我們就會清楚,傳輸層是屬于內核的,那么我們要通過網絡協議棧進行通信,必定調用的是傳輸層提供的系統調用,來進行的網絡通信。

在這里插入圖片描述

🌉認識TCP協議

此處我們先對TCP(Transmission Control Protocol 傳輸控制協議)有一個直觀的認識;后面我們再詳細討論TCP的一些細節問題.

  • 傳輸層協議
  • 有連接
  • 可靠傳輸
  • 面向字節流

🌉 認識UDP協議

此處我們也是對UDP(UserDatagramProtocol 用戶數據報協議)有一個直觀的認識;后面再詳細討論.

  • 傳輸層協議
  • 無連接
  • 不可靠傳輸
  • 面向數據報

🌠網絡字節序

我們已經知道,內存中的多字節數據相對于內存地址有大端和小端之分,磁盤文件中的多字節數據相對于文件中的偏移地址也有大端小端之分,網絡數據流同樣有大端小端之分. 那么如何定義網絡數據流的地址呢?

  • 發送主機通常將發送緩沖區中的數據按內存地址從低到高的順序發出;接收主機把從網絡上接到的字節依次保存在接收緩沖區中,也是按內存地址從低到高的順序保存;
  • 因此,網絡數據流的地址應這樣規定:先發出的數據是低地址,后發出的數據是高地址.
  • TCP/IP協議規定,網絡數據流應采用大端字節序,即低地址高字節.
  • 不管這臺主機是大端機還是小端機,都會按照這個TCP/IP規定的網絡字節序來發送/接收數據;
  • 如果當前發送主機是小端,就需要先將數據轉成大端;否則就忽略,直接發送即可

在這里插入圖片描述
為使網絡程序具有可移植性,使同樣的C代碼在大端和小端計算機上編譯后都能正常運行,可以調用以下庫函數做網絡字節序和主機字節序的轉換。

在這里插入圖片描述
這些函數名很好記,h表示host,n表示network,l表示32位長整數,s表示16位短整數。

  • 例如htonl表示將32位的長整數從主機字節序轉換為網絡字節序,例如將IP地址轉換后準備發送。
  • 如果主機是小端字節序,這些函數將參數做相應的大小端轉換然后返回;
  • 如果主機是大端字節序,這些函數不做轉換,將參數原封不動地返回。

🌠Socket 編程接口

🌉Socket 常見API

C// 創建 socket 文件描述符 (TCP/UDP, 客戶端 + 服務器)int socket(int domain, int type, int protocol);// 綁定端口號 (TCP/UDP, 服務器)int bind(int socket, const struct sockaddr *address,socklen_t address_len);// 開始監聽socket (TCP, 服務器)int listen(int socket, int backlog);// 接收請求 (TCP, 服務器)int accept(int socket, struct sockaddr* address,socklen_t* address_len);// 建立連接 (TCP, 客戶端)int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
  1. socket() - 創建網絡端點
int socket(int domain, int type, int protocol);
  • 功能:創建一個網絡通信的端點(socket描述符),類似于文件描述符,用于后續的網絡操作。
  • 參數
    • domain:協議族(地址族),指定網絡通信的地址類型,常見值:
      • AF_INET:IPv4協議
      • AF_INET6:IPv6協議
      • AF_UNIX:本地進程間通信(Unix域socket)
    • type:套接字類型,決定通信方式:
      • SOCK_STREAM:流式套接字,對應TCP協議(可靠、面向連接)
      • SOCK_DGRAM:數據報套接字,對應UDP協議(不可靠、無連接)
      • SOCK_RAW:原始套接字,用于直接訪問底層協議(如ICMP)
    • protocol:具體協議,通常設為0表示根據前兩個參數自動選擇默認協議
  • 返回值:成功返回非負的socket描述符,失敗返回-1并設置errno
  1. bind() - 綁定地址和端口
int bind(int socket, const struct sockaddr *address, socklen_t address_len);
  • 功能:將socket與特定的IP地址和端口號綁定(主要用于服務器端)。
  • 參數
    • socketsocket()返回的描述符
    • address:指向struct sockaddr(或其衍生結構,如struct sockaddr_in)的指針,包含要綁定的IP和端口
    • address_lenaddress結構體的長度
  • 典型用法(服務器端):
    struct sockaddr_in serv_addr;
    serv_addr.sin_family = AF_INET;         // IPv4
    serv_addr.sin_addr.s_addr = INADDR_ANY; // 綁定到所有本地網卡
    serv_addr.sin_port = htons(8080);       // 端口號(需轉換為網絡字節序)
    bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
    
  • 返回值:成功返回0,失敗返回-1
  1. listen() - 監聽連接請求
int listen(int socket, int backlog);
  • 功能:將流式套接字(TCP)轉為被動監聽狀態,準備接收客戶端連接(僅服務器端使用)。
  • 參數
    • socket:已綁定的socket描述符
    • backlog:未處理連接的最大隊列長度(超過此數的連接會被拒絕)
  • 注意:僅用于TCP協議,UDP無需監聽
  • 返回值:成功返回0,失敗返回-1
  1. accept() - 接收客戶端連接
int accept(int socket, struct sockaddr* address, socklen_t* address_len);
  • 功能:從監聽隊列中取出一個客戶端連接請求,創建新的socket用于與該客戶端通信(僅TCP服務器使用)。
  • 參數
    • socket:處于監聽狀態的socket描述符(監聽套接字)
    • address:輸出參數,用于存儲客戶端的地址信息
    • address_len:輸入輸出參數,傳入緩沖區長度,返回實際地址長度
  • 特點
    • 阻塞調用,若無連接會一直等待
    • 返回新的socket描述符(連接套接字),與客戶端的通信通過該描述符進行
    • 原監聽 socket繼續監聽新的連接
  • 返回值:成功返回新的socket描述符,失敗返回-1
  1. connect() - 建立連接
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • 功能:客戶端主動向服務器發起連接(僅TCP客戶端使用)。
  • 參數
    • sockfd:客戶端的socket描述符
    • addr:指向服務器地址結構的指針(包含服務器IP和端口)
    • addrlen:地址結構的長度
  • 特點
    • 觸發TCP三次握手過程
    • 阻塞調用,直到連接建立或失敗
  • 返回值:成功返回0,失敗返回-1

典型工作流程

  • TCP服務器socket()bind()listen()accept() → 讀寫數據
  • TCP客戶端socket()connect() → 讀寫數據
  • UDP(無連接):通常只需socket()bind()(服務器),無需listen()/accept()/connect()

🌉sockaddr 結構

socket API 是一層抽象的網絡編程接口,適用于各種底層網絡協議,如IPv4、IPv6,以及后面要講的UNIXDomainSocket.然而,各種網絡協議的地址格式并不相同.

在這里插入圖片描述

  • IPv4IPv6的地址格式定義在netinet/in.h中,IPv4地址用sockaddr_in結構體表示,包括16位地址類型,16位端口號和32IP地址.
  • IPv4、IPv6地址類型分別定義為常數AF_INETAF_INET6.這樣,只要取得某種sockaddr結構體的首地址,不需要知道具體是哪種類型的sockaddr結構體,就可以根據地址類型字段確定結構體中的內容.
  • socketAPI可以都用struct sockaddr *類型表示, 在使用的時候需要強制轉化成sockaddr_in; 這樣的好處是程序的通用性,可以接收IPv4, IPv6, 以及UNIXDomain
  • Socket 各種類型的sockaddr結構體指針做為參數;

  1. sockaddr 結構
/* Structure describing a generic socket address.  */
struct __attribute_struct_may_alias__ sockaddr{__SOCKADDR_COMMON (sa_);	/* Common data: address family and length.  */char sa_data[14];		/* Address data.  */};
  1. sockaddr_in 結構
/* Structure describing an Internet socket address.  */
struct __attribute_struct_may_alias__ sockaddr_in{__SOCKADDR_COMMON (sin_);in_port_t sin_port;			/* Port number.  */struct in_addr sin_addr;		/* Internet address.  *//* Pad to size of `struct sockaddr'.  */unsigned char sin_zero[sizeof (struct sockaddr)- __SOCKADDR_COMMON_SIZE- sizeof (in_port_t)- sizeof (struct in_addr)];};

雖然socket api的接口是sockaddr, 但是我們真正在基于IPv4編程時,使用的數據結構是sockaddr_in; 這個結構里主要有三部分信息:地址類型,端口號,IP地址.

🌉in_addr 結構

/* Internet address.  */
typedef uint32_t in_addr_t;
struct in_addr{in_addr_t s_addr;};

in_addr 用來表示一個IPv4IP地址.其實就是一個32位的整數


🚩總結

請添加圖片描述

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

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

相關文章

React+Next.js+Tailwind CSS 電商 SEO 優化

一、項目背景與技術選型?1. 原始痛點?項目最初基于純 React 開發&#xff08;SPA 架構&#xff09;&#xff0c;存在三個致命問題&#xff1a;?搜索引擎爬蟲無法有效抓取動態渲染的商品詳情、分類頁內容&#xff1b;?單頁面應用 難以實現頁面級的 meta 定制&#xff0c;關鍵…

Process Lasso:提升電腦性能的得力助手

在日常使用電腦的過程中&#xff0c;我們常常會遇到這樣的問題&#xff1a;電腦運行緩慢、程序響應遲緩、多任務處理時卡頓不斷。這些問題不僅影響工作效率&#xff0c;還讓人感到非常煩躁。其實&#xff0c;這些問題很多時候是因為電腦的進程管理不夠優化。而Process Lasso正是…

AI驅動的大前端內容創作與個性化推送:資訊類應用實戰指南

在信息爆炸的時代&#xff0c;資訊類應用面臨兩大核心挑戰&#xff1a;一是如何高效生產海量優質內容&#xff0c;二是如何讓用戶從海量信息中快速獲取感興趣的內容。AI技術的介入正在重構資訊類應用的開發模式&#xff0c;從內容生產到用戶觸達形成全鏈路智能化。本文將從開發…

2025/7/16——java學習總結

Java IO 流全體系總結&#xff1a;從基礎到實戰的完整突破&#xff08;重寫&#xff09;一、基礎核心&#xff1a;字節流與字符流的底層邏輯&#xff08;一&#xff09;字節流&#xff1a;二進制數據的讀寫基礎操作字節輸入流&#xff1a;掌握 FileInputStream 單字節讀取細節&…

書籍自然數數組的排序(8)0715

題目給定一個長度為N的整型數組arr&#xff0c;其中有N個互不相等的自然數1~N&#xff0c;請實現arr的排序&#xff0c;但是不要把下標0~N-1位置上的數通過直接賦值的方式替換成1~N。解答 arr在調整之后應該事下標從0到N-1的位置上依次放著1~N&#xff0c;即arr[index] index …

【08】MFC入門到精通——MFC模態對話框 和 非模態對話框 解析 及 實例演示

文章目錄八、模態對話框 和 非模態對話框 創建及顯示8.1 對話框是怎樣彈出的8.2 模態對話框的創建及顯示8.3 非模態對話框的創建及顯示8.4 完整代碼下載八、模態對話框 和 非模態對話框 創建及顯示 Windows對話框分為兩類&#xff1a;模態對話框 和 非模態對話框。 模態對話框…

github上傳大文件(多種解決方案)

之前一直用vscode的上傳項目方法&#xff0c;這個方便之處在于不用打開git終端輸入各種命令&#xff0c;不過麻煩的是我一直無法拉取github上的遠程倉庫提交&#xff0c;每次只能更新已有的倉庫并且上傳的文件還不能太大&#xff0c;應該是不能超過100MB&#xff0c;而且直接在…

生活污水深度除磷的方法

生活污水中磷含量過多的危害大家都知道總磷是水質檢測的重要指標之一&#xff0c;在污水處理中生活污水往往都會出現總磷超標的現象。生活污水磷超標的危害是多方面的主要包括水體富營養化、危害水生生物、影響人類健康&#xff0c;以及可能引發藍藻水華等問題。除磷方法污水的…

Flutter瀑布流布局深度實踐:打造高性能動態圖片墻

本文將深入探討如何在Flutter中實現高性能瀑布流布局&#xff0c;解決動態高度內容展示的核心難題&#xff0c;并帶來卓越的用戶體驗。引言&#xff1a;瀑布流布局的魅力 瀑布流布局(Pinterest-style layout)已成為現代應用展示圖片和內容的黃金標準。它通過錯落有致的排列方式…

OpenCV 伽馬校正函數gammaCorrection()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 該函數用于對輸入圖像應用伽馬校正&#xff08;Gamma Correction&#xff09;&#xff0c;這是一種非線性的圖像處理技術&#xff0c;主要用于調整…

Linux-局域網構建+VLAN 劃分 + 端口 MAC-IP 綁定 + 靜態 DHCP

文章目錄1. 適用于家庭、工作室或小型企業的局域網構建2. VLAN劃分3. VLAN 劃分 端口 MAC-IP 綁定 靜態 DHCP跳轉→網絡管理基礎復習 1. 適用于家庭、工作室或小型企業的局域網構建 ? 一、硬件連線&#xff08;一次到位&#xff09; 光纖入戶 → 光貓/寬帶調制解調器光貓…

滲透測試路線

滲透測試學習路線報告&#xff08;從入門到高級&#xff09; 引言&#xff1a;滲透測試概述與學習路線設計 滲透測試作為網絡安全體系中的核心實踐環節&#xff0c;通過模擬真實攻擊者的技術手段與攻擊路徑&#xff0c;主動識別信息系統中的安全漏洞、評估防護機制有效性&#…

Node.js 中http 和 http/2 是兩個不同模塊對比

1. 核心模塊對比 特性http 模塊 (HTTP/1.1)http2 模塊 (HTTP/2)協議版本HTTP/1.1&#xff08;文本協議&#xff09;HTTP/2&#xff08;二進制協議&#xff09;多路復用不支持&#xff08;需多個 TCP 連接&#xff09;支持&#xff08;單連接多流&#xff09;頭部壓縮無HPACK 壓…

3DGS之COLMAP

COLMAP 在 3DGS 中起到了數據預處理和三維重建的關鍵作用&#xff0c;其處理流程包括特征提取與匹配、稀疏重建、稠密重建和輸出文件生成。結合 3DGS 的高斯分布建模和優化算法&#xff0c;COLMAP 提供了場景的幾何和相機信息&#xff0c;為實時渲染和三維重建奠定了基礎。一、…

RabbitMQ中隊列長度限制(Queue Length Limit)詳解

在 RabbitMQ 中&#xff0c;隊列長度限制&#xff08;Queue Length Limit&#xff09;是指對隊列中消息數量的最大限制。當隊列中的消息數量達到設定的上限時&#xff0c;RabbitMQ 會根據配置的策略&#xff08;如丟棄舊消息、拒絕新消息或將消息轉移到另一個隊列&#xff09;來…

Python設計模式深度解析:建造者模式(Builder Pattern)完全指南

Python設計模式深度解析&#xff1a;建造者模式&#xff08;Builder Pattern&#xff09;完全指南前言什么是建造者模式&#xff1f;建造者模式的核心思想模式的核心組成實際案例一&#xff1a;UI選擇組件的動態構建抽象建造者基類具體建造者實現列表框建造者復選框建造者工廠建…

elementuiPlus+vue3手腳架后臺管理系統,上生產環境之后,如何隱藏vite.config.ts的target地址

在項目根目錄創建 .env.production 文件&#xff1a; VITE_API_TARGEThttps://your-real-api.com修改 vite.config.ts&#xff1a; import { defineConfig, loadEnv } from viteexport default defineConfig(({ mode }) > {const env loadEnv(mode, process.cwd(), )return…

ARCGIS PRO DSK 顏色選擇控件(ColorPickerControl)的調用

顏色選擇控件ColorPickerControl 。一、XAML 集成方式 1 、在WPF窗體上使用&#xff0c;xml&#xff1a;加入空間命名引用xmlns:ui1"clr-namespace:ArcGIS.Desktop.Internal.Mapping.Symbology;assemblyArcGIS.Desktop.Mapping" xmlns:uil"http://schemas.xceed…

深淺拷貝以及函數緩存

目錄 數據類型介紹 基本數據類型&#xff08;Primitive Types&#xff09; 引用數據類型&#xff08;Reference Types&#xff09; 淺拷貝 深拷貝 利用JSON的序列化和反序列化實現深拷貝 遞歸實現深拷貝 第三方庫lodash的cloneDeep 函數緩存的概念 實現方法 數據類型介…

第六屆信號處理與計算機科學國際學術會議(SPCS 2025)

重要信息 官網&#xff1a;www.icspcs.org &#xff08;詳情見官網&#xff09; 時間&#xff1a;2025年8月15-17日 地點&#xff1a;西安 主題 信號處理與智能計算計算科學與人工智能網絡與多媒體技術數字信號處理 雷達信號處理 通信信號處理 臨時和傳感器網絡 模擬和…