嵌入式LINUX——————網絡TCP

一、TCP連接

1.TCP特點:

(1)面向鏈接

(2)面向字節流

(3)安全可靠的傳輸協議,因為會先建立連接

(4)占用資源開銷大,效率低,實時性不佳,機制復雜

2.安全可靠機制

(1)三次握手:【客戶端發起】
指建立tcp連接時,需要客戶端和服務端總共發送三次報文確認連接。(確保雙方都已經 做好收發數據的準備)

????????ACK:響應報文

????????STN:請求建立一個連接


(2)四次揮手:【兩端都可發起】
斷開一個tcp連接,需要客戶端和服務端發送四個報文以確認斷開。(確保斷開前雙方都已經收發完畢)

FIN:finish標志,表示釋放連接

(3) 應答機制

每一個tcp頭部有個序列號和確認應答號,TCP給每一抱會有一個序列號,發送方會把第一個編號給序號,在接受方應答的時候,會把確認序列號置最后一個編號的下一個編號回應

通過序列號和確定序列號來確定收發的

(4)超時重傳機制

3.編程

(1)socket?

(2)connect

(1)功能: 發送三次握手鏈接請求
(2)參數:
sockfd:套接字文件描述符
addr:存放目的地址空間首地址
addrlen:目的地址長度
(3)返回值:
成功返回0?
失敗返回-1

(3)send

(1)功能:發送數據
(2)參數:
sockfd:套接字文件描述符
buf:存放數據空間首地址
len:數據長度
(3)返回值:
成功返回發送字節數
失敗返回-1

(4)recv? ? ?

(1)功能:接收數據?
(2)參數:
sockfd:套接字文件描述符
buf:存放數據空間首地址?
len:最多接收數據長度?
flags:接收屬性默認為0?
(3)返回值:
成功返回實際接收字節數
失敗返回-1?
對方連接斷開,直接返回,不在阻塞,沒有數據返回0;?

(5)bind

(6)listen

(1)功能:監聽三次握手鏈接請求
(2)參數:
sockfd:套接字文件描述符
backlog:最多允許等待尚未處理的三次握手鏈接個數
(3)返回值:
成功返回0?
失敗返回-1?

(7)accept

? ?

(1)功能::處理三次握手等待隊列中的第一個請求并建立一個用來通信的新套接字
(2)參數:
sockfd:套接字文件描述符
addr:存放發送端IP地址空間首地址?
addrlen:想要接收的IP地址的長度?
(3) 返回值:
成功返通訊套接字
失敗返回-1?

4.提高效率

(1)延遲應答

(2)捎帶應答

(3)流量控制機制

發送端根據窗口的數據大小,去動態控制發送端的數據;0--65535,接收端根據自己的能力,去調整窗口的大小,65535的時候,接受端處理能力最強,發送端可以發快一點。

(4)滑動窗口

? ? ? ? 滑動窗口大小:是TCP流量控制得一個手段。目的是告訴對方, 本端得TCP接受緩沖區還能容納多少字節得數據,這樣對方就可以控制發送數據的速度,從而達到流量控制,16bit,因而窗口最大65535.

? ? ? ? 本質是一段緩沖區:通過指針把緩沖區分為幾個部分:

? ? ? ? 已發送并且收到應答的數據、已發送未收到應答的數據、未發送但在對方處理能力內的數據;未發送但不在對方處理能力內的數據;

慢慢滑動,已發送并且收到的數據滑出。

二、?TCP粘包問題【高頻面試題】

? ? TCP協議是面向字節流的協議,接收方不知道消息的界限,不知道一次提取多少數據,這就造成了粘包問題。

1. 粘包問題出現的原因:?

(1)發送端:需要等緩沖區滿時才發送出去,造成粘包;發送數據太快

(2)接收端:不及時的接收緩沖區內的包,造成多個包接收。處理數據太慢導致數據在緩沖區緩存

2.避免粘包問題的方法:

(1)對于定長的包,保證每次都按固定大小發送和讀取即可;// ?結構體

? ? ? ? 1)問題:

? ? ? ? 結構體對齊問題:假設發送方和接收方分別32字節、64字節;在不同字節平臺結構體對齊長度不一樣;所以要確保雙方結構體對齊方式一樣;或者指定按照1個字節對齊,注意,結構體不可放指針;
在雙方通信時,發送方的發送數據類型不一樣,接收很難確認和區分接受的大小;所以不適用于數據類型多樣化;
(2) 對于變長的包,還可以在包和包之間使用明確的分隔符,這個分隔符是由程序員自己來定的,只要保證分隔符不和正文沖突即可。應用層根據分隔符進行解析

(3)自定義一個應用層的數據協議幀;

????????如果數據里面有幀頭或者幀尾 ====》在幀頭后面加入一個長度,這個長度規定,向后多少個

????????首先找幀頭和有效字節長度,向后讀有效字節長度并且讀完了看最后是不是幀尾

????????在后面加個校驗

????????所以包含:幀頭(AA)、幀尾(BB)、有效數據長度(len)、校驗(例如8位和校驗()、16位和校驗、CRC校驗、和其他復雜校驗算法)


三、TCP和UDP區別

????????都是網絡中傳輸層的傳輸協議

????????UDP叫做,無需建立鏈接、直接發送給接收方,需要對方的地址,面向數據包;存在丟包,盡最大努力叫覅,不安全不可靠;由于沒有很多機制,頭部小,資源開銷打;要求實時性、不要求數據;

????????TCP需要建立TXP鏈接,面向字節流,有一系列機制可以確保安全機制,三次握手四次揮手、應答機制、流量控制、流動窗口、超時重傳;由于很多機制。頭部大。資源開銷打,要求數據傳輸安全性高

四、代碼練習

????????(1)使用TCP實現全雙工(進程)

客戶端

#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include<unistd.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <sys/wait.h>
#include<pthread.h>
#include <errno.h>
int main()
{int sockfd = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in seraddr;seraddr.sin_family = AF_INET;seraddr.sin_port = htons(50001);seraddr.sin_addr.s_addr = inet_addr("192.168.245.128");char buf[1024] = {0};int ret = connect(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));if(ret < 0){perror("connect fail");return -1;}pid_t pid = fork();if(pid < 0){perror("fork fail");return -1;}if(pid > 0){while(1){memset(buf, 0, sizeof(buf));fgets(buf, sizeof(buf), stdin);ssize_t size = send(sockfd, buf, strlen(buf)-1, 0);if(size < 0){perror("send fail");return -1;}}}if(pid == 0){while(1){size_t size = recv(sockfd, buf, sizeof(buf), 0);if(size < 0 ){perror("recv fail");return -1;}if(size == 0){break;}buf[strlen(buf)] = '\0';printf("ser buf = %s\n",buf);}}close(sockfd);
}

服務端

#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include<unistd.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <sys/wait.h>
#include<pthread.h>
#include <errno.h>
int main()
{int sockfd = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in seraddr;seraddr.sin_family = AF_INET;seraddr.sin_port = htons(50001);seraddr.sin_addr.s_addr = inet_addr("192.168.245.128");char buf[1024] = {0};int ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));if(ret < 0){perror("bind fail");return -1;}ret = listen(sockfd, 10);if(ret < 0){perror("listen fail");return -1;}int connfd = accept(sockfd, NULL, NULL);if(connfd < 0){perror("connfd fail");return -1;}pid_t pid = fork();if(pid < 0){perror("fork fail");return -1;}if(pid > 0){while(1){ssize_t size = recv(connfd, buf, sizeof(buf), 0);if(size < 0){perror("size fail");return -1;}if(size == 0){break;}buf[strlen(buf)] = '\0';printf("buf = %s\n",buf);}}if(pid == 0){while(1){memset(buf, 0, sizeof(buf));fgets(buf, sizeof(buf), stdin);size_t size = send(connfd, buf, strlen(buf)-1, 0);if(size < 0){perror("send fail");return -1;}}}close(connfd);return 0;
}

? ? ? ? (2)使用TCP實現文件傳輸(傳輸過來的文件名不變)

客戶端

#include <fcntl.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include<unistd.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <sys/wait.h>
#include<pthread.h>
#include <errno.h>
int main()
{int sockfd = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in seraddr;seraddr.sin_family = AF_INET;seraddr.sin_port = htons(50025);seraddr.sin_addr.s_addr = inet_addr("192.168.1.193");char buf[1024] = {0};char buffer[1024] = {0};int ret = connect(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));if(ret < 0){perror("connect fail");return -1;}int fd = open("../1.txt", O_RDWR);int fp = open("2.txt", O_RDWR);if(fd < 0){perror("open fail");return -1;}if(fp < 0){perror("open fail");return -1;}pid_t pid = fork();if(pid < 0){perror("fork fail");return -1;}if(pid > 0){while(1){memset(buf, 0, sizeof(buf));memset(buffer, 0, sizeof(buffer));fgets(buf, sizeof(buf), stdin);if(strncmp(buf, "1.txt", 5) == 0){int ret1 =read(fd, buffer, sizeof(buffer));printf("ret1 = %d\n",ret1);// ssize_t size = send(sockfd, buffer, strlen(buffer)-1, 0);ssize_t size = send(sockfd, buffer, ret1, 0);if(size < 0){perror("send fail");return -1;}memset(buffer, 0, sizeof(buffer));}}}if(pid == 0){while(1){memset(buffer, 0, sizeof(buffer));size_t size = recv(sockfd, buffer, sizeof(buffer), 0);if(size < 0 ){perror("recv fail");return -1;}buffer[strlen(buffer)] = '\0';write(fp, buffer,strlen(buffer));//buf[strlen(buf)] = '\0';printf("ser buffer = %s\n",buffer);memset(buffer, 0, sizeof(buffer));}}close(sockfd);
}

服務端

#include <fcntl.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include<unistd.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <sys/wait.h>
#include<pthread.h>
#include <errno.h>
int main()
{int sockfd = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in seraddr;seraddr.sin_family = AF_INET;seraddr.sin_port = htons(50025);seraddr.sin_addr.s_addr = inet_addr("192.168.1.193");char buf[1024] = {0};char buffer[1024] = {0};int ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));if(ret < 0){perror("bind fail");return -1;}ret = listen(sockfd, 10);if(ret < 0){perror("listen fail");return -1;}int connfd = accept(sockfd, NULL, NULL);if(connfd < 0){perror("connfd fail");return -1;}int fd = open("1.txt", O_RDWR);int fp = open("../2.txt", O_RDWR);pid_t pid = fork();if(pid < 0){perror("fork fail");return -1;}if(pid > 0){while(1){memset(buffer, 0, sizeof(buffer));ssize_t size = recv(connfd, buffer, sizeof(buffer), 0);if(size < 0){perror("size fail");return -1;}buffer[strlen(buffer)] = '\0';write(fd, buffer,strlen(buffer));//buf[strlen(buf)] = '\0';printf("buffer = %s\n",buffer);memset(buffer, 0, sizeof(buffer));}}if(pid == 0){while(1){memset(buffer, 0, sizeof(buffer));memset(buf, 0, sizeof(buf));fgets(buf, sizeof(buf), stdin);if(strncmp(buf, "2.txt", 5) == 0){int ret1 =read(fp, buffer, sizeof(buffer));printf("ret1 = %d\n",ret1);size_t size = send(connfd, buffer, strlen(buffer)-1, 0);if(size < 0){perror("send fail");return -1;}memset(buffer, 0, sizeof(buffer));}}}close(connfd);return 0;
}

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

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

相關文章

alicloud 阿里云有哪些日志 審計日志

1: 阿里有哪些audit log: Audit Related Logs Below table describe the logs available in Log Service that might be applicable to the Security Operations Team. 2: 怎么來分析呢? Overview Its recommended to built a program with SLS Consumer Group which real…

如何理解AP服務發現協議中“如果某項服務需要被配置為可通過多個不同的網絡接口進行訪問,則應為每個網絡接口使用一個獨立的客戶端服務實例”?

上一句&#xff1a;[PRS_SOMEIPSD_00238]◎ 「如果某項服務需要在多個網絡接口上提供&#xff0c;則應為每個網絡接口使用一個獨立的服務器服務實例。」(RS_SOMEIPSD_00003) 本句&#xff1a;[PRS_SOMEIPSD_00239] 「如果某項服務需要被配置為可通過多個不同的網絡接口進行訪問…

piecewise jerk算法介紹

piecewise jerk算法介紹 piecewise jerk算法是百度Apollo中的一種用于路徑和速度平滑的算法&#xff0c;該算法假設相鄰點之間的jerk為常數&#xff0c;基于該假設將平滑問題構建為二次規劃問題&#xff0c;調用osqp求解器求解。參考論文為&#xff1a;Optimal Vehicle Path Pl…

分布式蜜罐系統的部署安裝

前陣子勒索病毒泛濫&#xff0c;中小企業由于缺少專業EDR&#xff0c;態勢感知&#xff0c;IPS等設備&#xff0c;往往是在勒索事件發生之后才后知后覺&#xff0c;也因為缺乏有效的備份策略&#xff0c;導致數據&#xff0c;經濟&#xff0c;商業信譽的喪失&#xff0c;甚至還…

定時器互補PWM輸出和死區

定時器互補PWM輸出和死區互補PWM&#xff08;Complementary PWM&#xff09;H橋、全橋、半橋中的應用為什么需要死區時間互補PWM&#xff08;Complementary PWM&#xff09; 是一種特殊的 PWM 輸出模式&#xff0c;通常用于H橋、全橋或半橋電路的驅動。其核心原理是利用定時器…

嵌入式ARM程序高級調試基礎:8.QEMU ARM虛擬機與tftp配置

嵌入式ARM程序高級調試基礎:8.QEMU ARM虛擬機與tftp配置 文章目錄 嵌入式ARM程序高級調試基礎:8.QEMU ARM虛擬機與tftp配置 一.總的網絡配置過程 二.主機配置 三.QEMU ARM 網絡配置 四.主機與虛擬器之間的網絡測試 五.TFTP網絡配置 5.1 ubuntu主機安裝tftp服務器 5.2 設置tft…

【貪心算法】貪心算法六

貪心算法六 1.壞了的計算器 2.合并區間 3.無重疊區間 4.用最少數量的箭引爆氣球 點贊????收藏????關注???? 你的支持是對我最大的鼓勵,我們一起努力吧!???? 1.壞了的計算器 題目鏈接: 991. 壞了的計算器 題目分析: 算法原理: 解法一:正向推導 以3轉化…

直播預約 | CATIA MODSIM SmartCAE帶練營第3期:讓每輪設計迭代都快人一步!

▼▼免費報名鏈接▼▼ 達索系統企業數字化轉型在線研討會https://3ds.tbh5.com/EventDetail.aspx?eid1195&frpt 迅筑官網 ??

OSI參考模型TCP/IP模型 二三事

計算機網絡的學習離不開OSI參考模型&TCP/IP模型對各層功能與任務的了解就是學習的主要內容其二者的區別也是我們應該了解的其中 擁塞控制和流量控制 就是各層功能中 兩個易混淆的概念流量控制&#xff08;Flow Control&#xff09;&#xff1a;解決的是發送方和接收方之間速…

DataStream實現WordCount

目錄讀取文本數據讀取端口數據事實上Flink本身是流批統一的處理架構&#xff0c;批量的數據集本質上也是流&#xff0c;沒有必要用兩套不同的API來實現。所以從Flink 1.12開始&#xff0c;官方推薦的做法是直接使用DataStream API&#xff0c;在提交任務時通過將執行模式設為BA…

imx6ull-驅動開發篇37——Linux MISC 驅動實驗

目錄 MISC 設備驅動 miscdevice結構體 misc_register 函數 misc_deregister 函數 實驗程序編寫 修改設備樹 驅動程序編寫 miscbeep.c miscbeepApp.c Makefile 文件 運行測試 MISC 驅動也叫做雜項驅動&#xff0c;也就是當某些外設無法進行分類的時候就可以使用 MISC…

C# 項目“交互式展廳管理客戶端“針對的是“.NETFramework,Version=v4.8”,但此計算機上沒有安裝它。

C# 項目“交互式展廳管理客戶端"針對的是".NETFramework,Versionv4.8”&#xff0c;但此計算機上沒有安裝它。 解決方法&#xff1a; C# 項目“交互式展廳管理客戶端"針對的是".NETFramework,Versionv4.8”&#xff0c;但此計算機上沒有安裝它。 下載地址…

FFmpeg及 RTSP、RTMP

FFmpeg 是一個功能強大的跨平臺開源音視頻處理工具集 &#xff0c;集錄制、轉碼、編解碼、流媒體傳輸等功能于一體&#xff0c;被廣泛應用于音視頻處理、直播、點播等場景。它支持幾乎所有主流的音視頻格式和協議&#xff0c;是許多媒體軟件&#xff08;如 VLC、YouTube、抖音等…

金山辦公的服務端開發工程師-25屆春招筆試編程題

1.作弊 溪染&#xff1a;六王畢&#xff0c;四海一&#xff1b;蜀山兀&#xff0c;阿房出。覆壓三百余里&#xff0c;隔離天日。驪山北構而西折&#xff0c;直走咸陽。二川溶溶&#xff0c;流入宮墻。五步一樓&#xff0c;十步一閣&#xff1b;廊腰縵回&#xff0c;檐牙高啄&am…

注意力機制中為什么q與k^T相乘是注意力分數

要理解 “qkT\mathbf{q} \times \mathbf{k}^TqkT 是注意力分數”&#xff0c;核心是抓住注意力機制的本質目標 ——量化 “查詢&#xff08;q&#xff09;” 與 “鍵&#xff08;k&#xff09;” 之間的關聯程度&#xff0c;而向量點積&#xff08;矩陣相乘的元素本質&#xff…

Krea Video:Krea AI推出的AI視頻生成工具

本文轉載自&#xff1a;Krea Video&#xff1a;Krea AI推出的AI視頻生成工具 - Hello123工具導航 ** 一、平臺定位與技術特性 Krea Video 是 Krea AI 推出的 AI 視頻生成工具&#xff0c;通過結合關鍵幀圖像與文本提示實現精準視頻控制。用戶可自定義視頻首尾幀、為每張圖片設…

C++初階(2)C++入門基礎1

C是在C的基礎之上&#xff0c;容納進去了面向對象編程思想&#xff0c;并增加了許多有用的庫&#xff0c;以及編程范式 等。熟悉C語言之后&#xff0c;對C學習有一定的幫助。 本章節主要目標&#xff1a; 補充C語言語法的不足&#xff0c;以及C是如何對C語言設計不合理的地方…

ANSI終端色彩控制知識散播(II):封裝的層次(Python)——不同的邏輯“一樣”的預期

基礎高階各有色&#xff0c;本原純真動乾坤。 筆記模板由python腳本于2025-08-22 18:05:28創建&#xff0c;本篇筆記適合喜歡終端色彩ansi編碼和python的coder翻閱。 學習的細節是歡悅的歷程 博客的核心價值&#xff1a;在于輸出思考與經驗&#xff0c;而不僅僅是知識的簡單復述…

前端無感刷新 Token 的 Axios 封裝方案

在現代前端應用中&#xff0c;基于 Token 的身份驗證已成為主流方案。然而&#xff0c;Token 過期問題常常困擾開發者 —— 如何在不打斷用戶操作的情況下自動刷新 Token&#xff0c;實現 "無感刷新" 體驗&#xff1f;本文將詳細介紹基于 Axios 的解決方案。什么是無…

【數據結構】線性表——鏈表

這里寫自定義目錄標題線性表鏈表&#xff08;鏈式存儲&#xff09;單鏈表的定義單鏈表初始化不帶頭結點的單鏈表初始化帶頭結點的單鏈表初始化單鏈表的插入按位序插入帶頭結點不帶頭結點指定結點的后插操作指定結點的前插操作單鏈表的刪除按位序刪除&#xff08;帶頭結點&#…