詳解TCP和UDP通信協議

目錄

OSI的七層模型的主要功能

tcp是什么

TCP三次握手

為什么需要三次握手,兩次握手不行嗎

TCP四次揮手

揮手會什么需要四次

什么是TCP粘包問題?發生的原因

原因

解決方案

UDP是什么

TCP和UDP的區別

網絡層常見協議

利用socket進行tcp傳輸代碼示例

客戶端

服務端

利用socket進行udp傳輸代碼示例

客戶端

服務端

注意tcp的send/recv和udp的sendto/recvfrom有一點區別

OSI的七層模型的主要功能

  • **物理層:**利用傳輸介質為數據鏈路層提供物理連接,實現比特流的透明傳輸。
  • **數據鏈路層:**接收來自物理層的位流形式的數據,并封裝成幀,傳送到上一層
  • **網絡層:**將網絡地址翻譯成對應的物理地址,并通過路由選擇算法為分組通過通信子網選擇最適當的路徑。
  • **傳輸層:**在源端與目的端之間提供可靠的透明數據傳輸
  • **會話層:**負責在網絡中的兩節點之間建立、維持和終止通信
  • **表示層:**處理用戶信息的表示問題,數據的編碼,壓縮和解壓縮,數據的加密和解密
  • **應用層:**為用戶的應用進程提供網絡通信服務

tcp是什么

TCP(Transmission Control Protocol 傳輸控制協議)是一種面向連接的、可靠的、基于字節流的傳輸層通信協議,即位于傳輸層。

TCP三次握手

三次握手(Three-way Handshake)其實就是指建立一個TCP連接時,需要客戶端和服務器總共發送3個包。進行三次握手的主要作用就是為了確認雙方的接收能力和發送能力是否正常、指定自己的初始化序列號為后面的可靠性傳送做準備。實質上其實就是連接服務器指定端口,建立TCP連接,并同步連接雙方的序列號和確認號,交換TCP窗口大小 信息。

為什么需要三次握手,兩次握手不行嗎

TCP四次揮手

建立一個連接需要三次握手,而終止一個連接要經過四次揮手(也有將四次揮手叫做四次握手的)。這由TCP的半關閉(half-close)造成的。所謂的半關閉,其實就是TCP提供了連接的一端在結束它的發送后還能接收來自另一端數據的能力。
TCP 的連接的拆除需要發送四個包,因此稱為四次揮手(Four-way handshake),客戶端或服務器均可主動發起揮手動作。

揮手會什么需要四次

什么是TCP粘包問題?發生的原因

一個完整的業務可能會被TCP拆分成多個包進行發送,也有可能把多個小的包封裝成一個大的數據包發送,即是無邊界的流傳輸,這個就是TCP的粘包問題。

  • 封包:封包就是在發送數據報的時候為每個TCP數據包加上一個包頭,將數據報分為包頭和包體兩個部分。包頭是一個固定長度的結構體,里面包含該數據包的總長度。
  • 拆包:接收方在接收到報文后提取包頭中的長度信息進行截取。

原因

1、應用程序寫入數據的字節大小大于套接字發送緩沖區的大小.

2、進行MSS大小的TCP分段。( MSS=TCP報文段長度-TCP首部長度)

3、以太網的payload大于MTU進行IP分片。(MTU指:一種通信協議的某一層上面所能通過的最大數據包大小。)

解決方案

1、消息定長。
2、在包尾部增加回車或者空格符等特殊字符進行分割
3、將消息分為消息頭和消息尾
4、使用其它復雜的協議,如RTMP協議等。

UDP是什么

是一種提供無連接的,盡最大努力的數據傳輸服務(不保證數據傳輸的可靠性)的通信協議,即位于傳輸層。

TCP和UDP的區別

1、TCP面向連接(如打電話要先撥號建立連接);UDP是無連接的前不需要建立連接

2、TCP提供可靠的服務。也就是說,通過TCP連接傳送的數據,,無差錯,不丟失,不重復,且按序到達;UDP盡最大努力交付,即不保證可靠交付

3、TCP面向字節流,實際上是TCP把數據看成一連串無結構的字節流:UDP是面向報文的,UDP沒有擁塞控制,因此網絡出現擁塞不會使源主機的發送速率降低(對實時應用很有用,如IP電話,實時視頻會議等)

4、每一條TCP連接只能是點到點的;UDP支持一對一,一對多,多對一和多對多的交互通信

5、TCP首部開銷20字節;UDP的首部開銷小,只有8個字節

6、TCP的邏輯通信信道是全雙工的可靠信道,UDP則是不可靠信道

7、UDP是面向報文的,發送方的UDP對應用層交下來的報文,不合并,不拆分,只是在其上面加上首部后就交給了下面的網絡層,論應用層交給UDP多長的報文,它統統發送,一次發送一個。而對接收方,接到后直接去除首部,交給上面的應用層就完成任務了。因此,它需要應用層控制報文的大小

TCP是面向字節流的,它把上面應用層交下來的數據看成無結構的字節流會發送,可以想象成流水形式的,發送方TCP會將數據放入“蓄水池”(緩存區),等到可以發送的時候就發送,不能發送就等著TCP會根據當前網絡的擁塞狀態來確定每個報文段的大小。

網絡層常見協議

利用socket進行tcp傳輸代碼示例

客戶端

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>#define PORT 8080int main() {int sock = 0;struct sockaddr_in serv_addr;char buffer[1024] = {0};// 創建 socket 文件描述符if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {std::cout << "Socket creation error" << std::endl;return -1;}serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(PORT);// 將服務端地址轉換為二進制if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {std::cout << "Invalid address / Address not supported" << std::endl;return -1;}// 連接到服務器if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {std::cout << "Connection Failed" << std::endl;return -1;}// 發送數據到服務器const char *hello = "Hello from client";send(sock, hello, strlen(hello), 0);std::cout << "Hello message sent" << std::endl;// 讀取服務器發送的數據int valread = read(sock, buffer, 1024);std::cout << "Received: " << buffer << std::endl;close(sock);return 0;
}

服務端

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>#define PORT 8080int main() {int server_fd, new_socket;struct sockaddr_in address;int opt = 1;int addrlen = sizeof(address);char buffer[1024] = {0};// 創建 socket 文件描述符if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);}// 將 socket 綁定到端口 8080if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {perror("setsockopt");close(server_fd);exit(EXIT_FAILURE);}address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("bind failed");close(server_fd);exit(EXIT_FAILURE);}// 監聽連接if (listen(server_fd, 3) < 0) {perror("listen");close(server_fd);exit(EXIT_FAILURE);}// 接受客戶端連接if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {perror("accept");close(server_fd);exit(EXIT_FAILURE);}// 讀取客戶端發送的數據int valread = read(new_socket, buffer, 1024);std::cout << "Received: " << buffer << std::endl;// 發送數據到客戶端const char *hello = "Hello from server";send(new_socket, hello, strlen(hello), 0);std::cout << "Hello message sent" << std::endl;close(new_socket);close(server_fd);return 0;
}

利用socket進行udp傳輸代碼示例

客戶端

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>#define PORT 8080int main() {int sockfd;char buffer[1024];struct sockaddr_in servaddr;// 創建 socket 文件描述符if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {perror("socket creation failed");exit(EXIT_FAILURE);}memset(&servaddr, 0, sizeof(servaddr));// 填寫服務器信息servaddr.sin_family = AF_INET;servaddr.sin_port = htons(PORT);servaddr.sin_addr.s_addr = INADDR_ANY;// 發送消息到服務器const char *hello = "Hello from client";sendto(sockfd, hello, strlen(hello), MSG_CONFIRM, (const struct sockaddr *)&servaddr, sizeof(servaddr));std::cout << "Hello message sent." << std::endl;// 接收服務器消息int n;socklen_t len;n = recvfrom(sockfd, (char *)buffer, 1024, MSG_WAITALL, (struct sockaddr *)&servaddr, &len);buffer[n] = '\0';std::cout << "Server : " << buffer << std::endl;close(sockfd);return 0;
}

服務端

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>#define PORT 8080int main() {int sockfd;char buffer[1024];struct sockaddr_in servaddr, cliaddr;// 創建 socket 文件描述符if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {perror("socket creation failed");exit(EXIT_FAILURE);}memset(&servaddr, 0, sizeof(servaddr));memset(&cliaddr, 0, sizeof(cliaddr));// 填寫服務器信息servaddr.sin_family = AF_INET; // IPv4servaddr.sin_addr.s_addr = INADDR_ANY;servaddr.sin_port = htons(PORT);// 綁定 socketif (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {perror("bind failed");close(sockfd);exit(EXIT_FAILURE);}int n;socklen_t len;len = sizeof(cliaddr); // 客戶端地址長度// 接收客戶端消息n = recvfrom(sockfd, (char *)buffer, 1024, MSG_WAITALL, (struct sockaddr *)&cliaddr, &len);buffer[n] = '\0';std::cout << "Client : " << buffer << std::endl;// 發送消息到客戶端const char *hello = "Hello from server";sendto(sockfd, hello, strlen(hello), MSG_CONFIRM, (const struct sockaddr *)&cliaddr, len);std::cout << "Hello message sent." << std::endl;close(sockfd);return 0;
}

注意tcp的send/recv和udp的sendto/recvfrom有一點區別

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

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

相關文章

【js面試題】深入理解DOM操作:創建、查詢、更新、添加和刪除節點

面試題&#xff1a;DOM常見的操作有哪些 引言&#xff1a; 在前端開發中&#xff0c;DOM&#xff08;文檔對象模型&#xff09;操作是日常工作中不可或缺的一部分。DOM提供了一種以編程方式訪問和更新文檔內容、結構和樣式的接口。 任何html或 xml 文檔都可以用dom表示為一個由…

KIVY Button?

Button — Kivy 2.3.0 documentation Button Jump to API ? Module: kivy.uix.button Added in 1.0.0 The Button is a Label with associated actions that are triggered when the button is pressed (or released after a click/touch). To configure the button, the s…

【論文速讀】| 用于安全漏洞防范的人工智能技術

本次分享論文&#xff1a;Artificial Intelligence Techniques for Security Vulnerability Prevention 基本信息 原文作者&#xff1a;Steve Kommrusch 作者單位&#xff1a;Colorado State University, Department of Computer Science, Fort Collins, CO, 80525 USA 關鍵…

ISO/OSI七層模型

ISO:國際標準化/ OSI:開放系統互聯 七層協議必背圖 1.注意事項&#xff1a; 1.上三層是為用戶服務的&#xff0c;下四層負責實際數據傳輸。 2.下四層的傳輸單位&#xff1a; 傳輸層&#xff1b; 數據段&#xff08;報文&#xff09; 網絡層&#xff1a; 數據包&#xff08;報…

1Panel安裝命令腳本大全,多Linux操作系統版本

1Panel安裝命令腳本大全&#xff0c;包括RedHat、CentOS、Ubuntu、Debian和openEuler等linux操作系統&#xff0c;碼筆記整理1Panel安裝命令腳本清單&#xff1a; RedHat/CentOS安裝命令&#xff1a; curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh…

【Swoole 的生命周期,文件描述符,協程數量,以及默認值】

目錄 Swoole 的生命周期 Swoole 文件描述符&#xff08;FD&#xff09;緩存 Swoole設置協程的數量 Swoole 默認值 Swoole 是一個基于 PHP 的高性能網絡通信引擎&#xff0c;它采用 C 編寫&#xff0c;提供了協程和高性能的網絡編程支持。Swoole 支持多種網絡服務器和客戶端…

python庫 - modelscope

ModelScope 是一個集成的機器學習模型庫&#xff0c;旨在簡化機器學習模型的使用流程&#xff0c;提供多種預訓練模型&#xff0c;涵蓋計算機視覺、自然語言處理、語音識別等多個領域。用戶可以輕松訪問、使用和分享各種預訓練的機器學習模型&#xff0c;無需從頭開始訓練模型&…

Vue項目openlayers中使用jsts處理wkt和geojson的交集-(geojson來源zpi解析)

Vue項目openlayers中使用jsts處理wkt和geojson的交集-(geojson來源zpi解析) 讀取壓縮包中的shape看上一篇筆記&#xff1a;Vue項目讀取zip中的ShapeFile文件&#xff0c;并解析為GeoJson openlayers使用jsts官方示例&#xff1a;https://openlayers.org/en/latest/examples/j…

框選table單元格,高亮展示

td單元格內&#xff0c;有未知層dom結構 <style>.highlight {background-color: yellow;} </style> <table id"myTable"><colgroup><col style"background-color: lightblue;"><col style"background-color: light…

#pragma 指令

#pragma 指令作用是設定編譯器的狀態或者是指示編譯器完成一些特定的動作 message 參數能夠在編譯信息輸出窗口中輸出相應的信息 #pragma message(“消息文本”) code_seg參數能夠設置程序中函數代碼存放的代碼段&#xff0c;當我們開發驅動程序的時候就會使用到它 #pragma…

科技創新引領水利行業升級:深入分析智慧水利解決方案的核心價值,展望其在未來水資源管理中的重要地位與作用

目錄 引言 一、智慧水利的概念與內涵 二、智慧水利解決方案的核心價值 1. 精準監測與預警 2. 優化資源配置 3. 智能運維管理 4. 公眾參與與決策支持 三、智慧水利在未來水資源管理中的重要地位與作用 1. 推動水利行業轉型升級 2. 保障國家水安全 3. 促進生態文明建設…

下降npm版本

Node版本與NPM版本對應關系 Node版本與NPM版本對應關系_node對應npm版本-CSDN博客 要降低npm的版本&#xff0c;可以按照以下步驟進行操作 1.首先&#xff0c;打開終端或命令提示符窗口。 2.輸入以下命令來檢査當前安裝的npm版本: npm -v 3.如果你想要降低npm的版本&#xff…

vb.netcad二開自學筆記5:ActiveX鏈接CAD的.net寫法

一、必不可少的對象引用 使用activex需要在項目屬性中勾選以下兩個引用&#xff0c;若找不到&#xff0c;則瀏覽定位直接添加下面兩個文件&#xff0c;可以看到位于cad的安裝路徑下&#xff0c;圖中的3個mgd.dll也可以勾選。 C:\Program Files\Autodesk\AutoCAD 2024\Autodes…

實戰 | YOLOv8使用TensorRT加速推理教程(步驟 + 代碼)

導 讀 本文主要介紹如何使用TensorRT加速YOLOv8模型推理的詳細步驟與演示。 YOLOv8推理加速的方法有哪些? YOLOv8模型推理加速可以通過多種技術和方法實現,下面是一些主要的策略: 1. 模型結構優化 網絡剪枝:移除模型中不重要的神經元或連接,減少模型復雜度。 模型精…

中文大模型基準測評2024上半年報告

中文大模型基準測評2024上半年報告 原創 SuperCLUE CLUE中文語言理解測評基準 2024年07月09日 18:09 浙江 SuperCLUE團隊 2024/07 背景 自2023年以來&#xff0c;AI大模型在全球范圍內掀起了有史以來規模最大的人工智能浪潮。進入2024年&#xff0c;全球大模型競爭態勢日益加…

Obsidian 文檔編輯器

Obsidian是一款功能強大的筆記軟件 Download - Obsidian

降Compose十八掌之『見龍在田』| Modifier

公眾號「稀有猿訴」 原文鏈接 降Compose十八掌之『見龍在田』| Modifier 通過前面的文章我們學會了如何使用元素來構建和填充我們的UI頁面&#xff0c;但這只完成了一半&#xff0c;元素還需要裝飾&#xff0c;以及進行動畫和事件響應&#xff0c;這才能生成完整的UI。這…

2.5章節python中布爾類型

在Python中&#xff0c;布爾類型&#xff08;Boolean type&#xff09;用于表示真&#xff08;True&#xff09;或假&#xff08;False&#xff09;的值。這是編程中非常基礎且重要的一個概念&#xff0c;因為它允許程序進行條件判斷&#xff0c;從而根據條件執行不同的代碼塊。…

智慧校園行政辦公-紅頭文件功能概述

在智慧校園的行政辦公系統中&#xff0c;紅頭文件的管理功能是一項重要的組成部分&#xff0c;它極大地提升了文件處理的效率與規范性。該功能圍繞文件的創建、審批、歸檔等關鍵環節&#xff0c;進行了全面的數字化改造。 首先&#xff0c;系統內置了多種標準化的紅頭文件模板&…

一文實踐強化學習訓練游戲ai--doom槍戰游戲實踐

一文實踐強化學習訓練游戲ai–doom槍戰游戲實踐 上次文章寫道下載doom的環境并嘗試了簡單的操作&#xff0c;這次讓我們來進行對象化和訓練、驗證&#xff0c;如果你有基礎&#xff0c;可以直接閱讀本文&#xff0c;不然請你先閱讀Doom基礎知識&#xff0c;其中包含了下載、動作…