TCP day39

六:C/S和B/S端

C/S:Client, server
B/S:Browser server

1.cs 專用客戶端 bs 通用客戶端
2.協議不同
Cs 標準協議,自定義協議
Bs http 超文本傳輸
3.cs 功能復雜 bs 功能弱
4.bs 資源都在ser,有ser發送到cli
cs 大部分資源都在cli

七:UDP和TCP特性

UDP:

  1. 無連接
    不需要維護繁雜網絡狀態。網絡開銷小。通信雙方通信過程,無法知道對方進程關閉。如果需要告知,需要發信息通知。
  2. 不可靠,
    傳輸數據的過程中,會有丟包。但是實時性好。適用直播 視頻傳輸,音頻傳輸。
    3.很容易實現一對多 。
    4.可以組播,廣播

TCP:

1.有鏈接,一次會話中,鏈接一直保持。如果一個斷開,另外一方可以感知
2.可靠 。靠機制保障。應答超時重傳

八:流式套接字

流式套接字 是一種tcp socket 隊列
1.有順序,連續
2.發送和接收的次數不需要對應。
3.send 發送快,寫阻塞

流式套接字 是一種tcp socket 隊列
1.有順序,連續
2.發送和接收的次數不需要對應。
3.send 發送快,寫阻塞

流式套接字 是一種tcp socket 隊列
1.有順序,連續
2.發送和接收的次數不需要對應。
3.send 發送快,寫阻塞

  1. 數據之間沒有邊界

數據沒有邊界會導致數據的黏包
接收收到數據后,無法正常解析

解決方法1.協商邊界
2.固定大小
3.自定義協議

//3.
eg:		AA       03      1 2 3        crc     BB開始    長度     數據      校驗      結束//都是自己定義的形式

九:TCP服務器和客戶端函數流程

服務器
socket(); 打開網絡設備 獲得文件描述符(套接字) listfd 監聽套接字,作用,就是三次握手
bind();// 給套接字設定ip(確定主機)+port(對應到進程pid)
listen(); 使監聽套集字進入監聽狀態(可以被三次握手的狀態)
accept();// 服務器和客戶端進入三次握手階段,并建立連接。并獲得通信套接字(服務器和客戶端后續進行通信,用的套接字)
recv() ;;//阻塞接收客戶端的數據。 0 ==ret 代表對方斷開連接。-1 ,代表錯誤。 >0 實際接收到的字節數。
send();//發送的數據。 發送過程中有可能阻塞。發送的快,把對方的緩沖區填滿就阻塞。
close().當收到對方的斷開請求(0 == recv())。就斷開與客戶端的通信。
客戶端
socket(); 打開網絡設備 獲得文件描述符(套接字) ,通信套接字
connect();客戶端主動連接服務器 。觸發三次握手。
send() ;//發送的數據。 發送過程中有可能阻塞。發送的快,把對方的緩沖區填滿就阻塞。
recv();//阻塞接收客戶端的數據。 0 ==ret 代表對方斷開連接。-1 ,代表錯誤。 >0 實際接收到的字節數。
close(); 當客戶端請求服務完成后,主動關閉套接字。觸發四次揮手。

9.1:三次握手/四次揮手
三次握手
c->syn(請求連接), c_num(起始發送數據的編號)   -> s 
s->syn,ACK(應答)S_num(起始發送數據的編號)->c 
c -> ACK  ->s 四次揮手
c->FIN(斷開連接)->ACK-> s 
s->ACK (應答上次fin的請求)->c 
s-> FIN(斷開連接) +ACK (應答上次fin的請求)->c 
c -> ACK(s-> FIN(斷開連接))->s

十:服務器端

10.1:listen
int listen(int sockfd, int backlog);

功能:在參數1所在的套接字id上監聽等待鏈接。
參數:sockfd 套接字id
backlog 允許鏈接的個數。
返回值:成功 0, 失敗 -1;

10.2:accept
int accept(int sockfd, struct sockaddr *addr,socklen_t *addrlen);// 這里有阻塞

功能:從已經監聽到的隊列中取出有效的客戶端鏈接并接入到當前程序。
參數:sockfd 套接字id
addr 如果該值為NULL ,表示不論客戶端是誰都接入。
如果要獲取客戶端信息,則事先定義變量并傳入變量地址,函數執行完畢將會將客戶端信息存儲到該變量中。
addrlen: 參數2的長度,如果參數2為NULL,則該值也為NULL;
如果參數不是NULL,&len;
一定要寫成len = sizeof(struct sockaddr);

返回值:成功 返回一個用于通信的新套接字id;從該代碼之后所有通信都基于該id, 失敗 -1;

10.3:recv
ssize_t recv(int sockfd, void *buf, size_t len,int flags);

功能:從指定的sockfd套接字中以flags方式獲取長度
為len字節的數據到指定的buff內存中。
參數:sockfd
如果服務器則是accept的返回值的新fd
如果客戶端則是socket的返回值舊fd
buff 用來存儲數據的本地內存,一般是數組或者
動態內存。
len 要獲取的數據長度
flags 獲取數據的方式,0 表示阻塞接受。

返回值:成功 表示接受的數據長度,一般小于等于len
失敗 -1;

十一:客戶端

11.1:connect
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

功能:該函數固定有客戶端使用,表示從當前主機向目標
主機發起鏈接請求。
參數:sockfd 本地socket創建的套接子id
addr 遠程目標主機的地址信息。
addrlen: 參數2的長度。
返回值:成功 0, 失敗 -1;
ps:套接字不是單獨給網絡用的,可以用別名強轉

11.2:send
int send(int sockfd, const void *msg, size_t len, int flags);

功能:從msg所在的內存中獲取長度為len的數據以flags 方式寫入到sockfd對應的套接字中。

參數:sockfd:如果是服務器則是accept的返回值新fd
如果是客戶端則是sockfd的返回值舊fd

? msg: 要發送的消息
? len: 要發送的消息長度
? flags :消息的發送方式。

返回值:成功 發送的字符長度, 失敗 -1;

十二:實例

//ser
#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h> /* See NOTES */
#include <time.h>
#include <unistd.h>
typedef struct sockaddr*(SA);
int main(int argc, char** argv)
{//監聽套接字 功能檢測是否有客戶端 連連接服務器int listfd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == listfd){perror("socket");return 1;}struct sockaddr_in ser, cli;bzero(&ser, sizeof(ser));bzero(&cli, sizeof(cli));ser.sin_family = AF_INET;ser.sin_port = htons(50000);// 代表本機地址  外部客戶端可以連接到服務器ser.sin_addr.s_addr = INADDR_ANY;//任何人都可以連接,相當于ser.sin_addr.s_addr = 0int ret = bind(listfd, (SA)&ser, sizeof(ser));if (-1 == ret){perror("bind");return 1;}// 同一時刻可以服務器建立連接的排隊數listen(listfd, 3);socklen_t len = sizeof(cli);//和客戶端建立連接,并獲得通信套接字,這個套接字就代表客戶端int conn = accept(listfd, (SA)&cli, &len);if (-1 == conn){perror("accept");return 1;}while (1){char buf[512] = {0};int rec_ret= recv(conn, buf, sizeof(buf), 0);if(rec_ret<=0){break;}printf("from cli:%s\n",buf);time_t tm;time(&tm);sprintf(buf, "%s %s", buf, ctime(&tm));int sd_ret = send(conn, buf, strlen(buf), 0);if(sd_ret<=0){break;}}close(listfd);close(conn);// system("pause");return 0;
}
//cli
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h> /* See NOTES */
#include <time.h>
#include <unistd.h>
typedef struct sockaddr *(SA);int main(int argc, char **argv)
{int conn = socket(AF_INET, SOCK_STREAM, 0);if (-1 == conn){perror("socket");return 1;}struct sockaddr_in ser;bzero(&ser, sizeof(ser));ser.sin_family = AF_INET;ser.sin_port = htons(50000);// 代表本機地址  外部客戶端可以連接到服務器ser.sin_addr.s_addr = inet_addr("192.168.116.130");int ret = connect(conn, (SA)&ser, sizeof(ser));if (-1 == ret){perror("connect");return 1;}while (1){char buf[512] = "hello,this tcp test";int sd_ret = send(conn, buf, strlen(buf), 0);if(sd_ret<=0){break;}bzero(buf, sizeof(buf));int ret_rec = recv(conn, buf, sizeof(buf), 0);if(ret_rec<=0){break;}printf("from  ser:%s\n",buf);sleep(1);}close(conn);// system("pause");return 0;
}

十三:tcp_cp_struct

//ser
#include <fcntl.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h> /* See NOTES */
#include <time.h>
#include <unistd.h>
typedef struct sockaddr*(SA);
typedef struct
{char name[256];int size;char buf[4096];int buf_size;} MSG;
int main(int argc, char** argv)
{//監聽套接字 功能檢測是否有客戶端 連連接服務器int listfd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == listfd){perror("socket");return 1;}struct sockaddr_in ser, cli;bzero(&ser, sizeof(ser));bzero(&cli, sizeof(cli));ser.sin_family = AF_INET;ser.sin_port = htons(50000);// 代表本機地址  外部客戶端可以連接到服務器ser.sin_addr.s_addr = INADDR_ANY;int ret = bind(listfd, (SA)&ser, sizeof(ser));if (-1 == ret){perror("bind");return 1;}// 同一時刻可以服務器建立連接的排隊數listen(listfd, 3);socklen_t len = sizeof(cli);//和客戶端建立連接,并獲得通信套接字,這個套接字就代表客戶端int conn = accept(listfd, (SA)&cli, &len);if (-1 == conn){perror("accept");return 1;}MSG msg;bzero(&msg, sizeof(msg));int flag = 0;int fd = -1;int total_size = 0;int currnet_size = 0;while (1){int re_ret = recv(conn, &msg, sizeof(msg), 0);if (re_ret <= 0){break;}if (0 == flag){flag = 1;fd = open(msg.name, O_WRONLY | O_CREAT | O_TRUNC, 0666);if (-1 == fd){perror("open");return 1;}total_size = msg.size;}if (msg.buf_size <= 0){break;}write(fd, msg.buf, msg.buf_size);currnet_size += msg.buf_size;printf("size:%d\n", currnet_size);if (currnet_size == total_size){  //文件傳輸結束break;}bzero(&msg, sizeof(msg));strcpy(msg.buf, "go on");send(conn, &msg, sizeof(msg), 0);}close(listfd);close(conn);close(fd);// system("pause");return 0;
}
//cli
#include <arpa/inet.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h> /* See NOTES */
#include <time.h>
#include <unistd.h>
typedef struct sockaddr *(SA);
typedef struct
{char name[256];int size;char buf[4096];int buf_size;} MSG;
int main(int argc, char **argv)
{int conn = socket(AF_INET, SOCK_STREAM, 0);if (-1 == conn){perror("socket");return 1;}struct sockaddr_in ser;bzero(&ser, sizeof(ser));ser.sin_family = AF_INET;ser.sin_port = htons(50000);// 代表本機地址  外部客戶端可以連接到服務器ser.sin_addr.s_addr = inet_addr("192.168.116.130");int ret = connect(conn, (SA)&ser, sizeof(ser));if (-1 == ret){perror("connect");return 1;}MSG msg;strcpy(msg.name, "2.png");struct stat st;ret = stat("/home/linux/1.png", &st);if (-1 == ret){perror("stat");return 1;}msg.size = st.st_size;int fd = open("/home/linux/1.png", O_RDONLY);if (-1 == fd){perror("open");return 1;}while (1){msg.buf_size = read(fd, msg.buf, sizeof(msg.buf));send(conn, &msg, sizeof(msg), 0);  // 固定大小的方式if (msg.buf_size <= 0){break;}bzero(&msg, sizeof(msg));recv(conn, &msg, sizeof(msg), 0);}close(conn);// system("pause");return 0;
}

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

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

相關文章

6 種無線傳輸照片從安卓到 Mac 的方法

將大量照片從安卓設備傳輸到電腦上&#xff0c;不僅可以備份照片&#xff0c;還能釋放設備存儲空間。雖然使用 USB 數據線可以在 Windows 電腦上輕松完成傳輸&#xff0c;但將安卓手機連接到 Mac 并非如此簡單。因此&#xff0c;許多用戶更傾向于無線傳輸照片從安卓到 Mac。您可…

在vscode 使用 remote-ssh

vscode安裝插件Remote-SSH,直接安裝即可 安裝完畢之后 在左下角有這個圖標 點擊之后選擇連接到主機然后選擇添加新鏈接之后輸入用戶名和主機地址 非默認端口使用 -p 端口號之后選擇第一個即可如果使用的是密碼,直接連接,然后輸入密碼即可如果使用的密鑰,則修改.ssh\config文件中…

RabbitMQ03——面試題

目錄 一、mq的作用和使用場景 二、mq的優點 2.1架構設計優勢 2.2功能特性優勢 2.3性能與可靠性優勢 2.4生態系統優勢 2.5對比優勢 三、mq的缺點 3.1性能與擴展性限制 3.2功能局限性 3.3運維復雜度 3.4與其他消息隊列的對比劣勢 四、mq相關產品&#xff0c;每種產品…

應用層攻防啟示錄:HTTP/HTTPS攻擊的精準攔截之道

一、七層攻擊的復雜性 # CC攻擊模擬工具&#xff08;Python實現&#xff09; import requests import threadingtarget_url "https://example.com/search?q"def cc_attack():while True:# 構造惡意搜索請求malicious_query "0" * 1000 # 長查詢參數try…

.net 警告【代碼 CS1998】此異步方法缺少 “await“ 運算符,將以同步方式運行。

【代碼 CS1998】此異步方法缺少 “await” 運算符&#xff0c;將以同步方式運行。請考慮使用 “await” 運算符等待非阻止的 API 調用&#xff0c;或者使用 “await Task.Run(…)” 在后臺線程上執行占用大量 CPU 的工作。在 VS 2022 中遇到的 CS1998 編譯器警告&#xff0c;表…

【自動駕駛黑科技】基于Frenet坐標系的車道變換軌跡規劃系統實現(附完整代碼)

1. 代碼結構概覽該代碼實現了一個車道變換軌跡規劃系統&#xff0c;包含兩個核心模塊&#xff1a;道路建模&#xff08;EnhancedRoadModel&#xff09;&#xff1a;基于樣條曲線構建道路模型。軌跡規劃&#xff08;LaneChangePlanner&#xff09;&#xff1a;根據障礙物狀態和道…

uni-calendar自定義簽到打卡顏色

uni-calendar自定義簽到打卡顏色&#xff0c;只需要將打卡的狀態添加到動態類class中即可 效果&#xff1a;在uni-modules >>> components >>> uni-calendar >>> uni-calendar-item.vue文件中&#xff0c;根據info對應的文字或者符號添加不同的clas…

浙江大學PTA程序設計C語言基礎編程練習題1-5

&#x1f30f;個人博客主頁&#xff1a;意疏-CSDN博客 希望文章能夠給到初學的你一些啟發&#xff5e; 如果覺得文章對你有幫助的話&#xff0c;點贊 關注 收藏支持一下筆者吧&#xff5e; 閱讀指南&#xff1a;開篇說明題目一、厘米換算英寸題目二、然后是幾點題目三、 逆序…

catkin build的config設置指南[設置多種make模式或策略]

在本篇文章中&#xff0c;我們來盡可能詳細地深入探討 catkin config 的使用方法。這是掌握 catkin_tools 工作流的關鍵&#xff0c;能極大地提升你的開發效率和項目的規范性。 catkin config 的核心思想 首先&#xff0c;要理解它的核心思想&#xff1a;為你的 Catkin 工作空間…

Ubuntu掛載和取消掛載

在 Ubuntu 中&#xff0c;掛載&#xff08;Mount&#xff09;和取消掛載&#xff08;Unmount&#xff09;是管理存儲設備&#xff08;如硬盤、U盤、ISO鏡像等&#xff09;的常見操作。以下是詳細指南&#xff1a;1. 掛載&#xff08;Mount&#xff09; 1.1 查看可用存儲設備 ls…

Vue開發常用庫(含npm安裝命令)

Vue開發常用庫&#xff08;含npm安裝命令&#xff09; 核心生態系統&#xff1a;Vue Router - 官方路由管理器 npm install vue-router4 # Vue 3 npm install vue-router3 # Vue 2Pinia - 新一代狀態管理庫 npm install piniaVuex - 傳統狀態管理庫 npm install vuexnext …

[硬件電路-39]:激光光路的光信號處理、模擬電路的電信號處理、數字電路的電信號處理、軟件的信號處理,有哪些共通的操作、運算、變換?

激光光路、模擬電路、數字電路及軟件中的信號處理在操作、運算和變換層面存在顯著共性&#xff0c;這些共性體現了信號處理的核心邏輯在不同技術領域的通用性。以下是具體分析&#xff1a; 目錄 一、共通操作&#xff1a;信號處理的基礎動作 1、放大與衰減 2、濾波 3、調制…

Grails(Groovy)框架拋出NoHandlerFoundException而不是返回404 Not Found

本文記錄在基于Spring(Boot)框架&#xff08;使用Java語言&#xff09;和Grails框架&#xff08;使用Groovy語言&#xff09;下&#xff0c;開發Controller接口&#xff0c;對不存在的URL請求&#xff0c;接口返回404 not found&#xff0c;而不是拋出NoHandlerFoundException異…

muduo中事件循環線程池的理解

事件循環線程池的理解前置知識reactor模型thread::start()方法的理解創建線程池子線程被喚醒的幾種情況子線程被主線程喚醒新連接到來有消息需要發送時&#xff08;多reactor情況時&#xff09;關閉連接時子線程被喚醒執行任務在 上一篇中&#xff0c;我們討論了關于簡單的線程…

AI智能體“上下文工程”實踐:來自 Manus 項目的經驗總結

轉載&#xff1a;https://manus.im/blog/Context-Engineering-for-AI-Agents-Lessons-from-Building-Manus 在啟動 Manus (manus.im/app) 項目之初&#xff0c;我的團隊面臨一個關鍵抉擇&#xff1a;究竟是基于開源基礎模型訓練一個端到端的智能體模型&#xff0c;還是在前沿大…

day19 鏈表

定義鏈式存儲的線性表頭文件相關定義 typedef int datatype;//定義數據域類型 typedef struct Node {union{int len; //頭結點數據域datatype data; //普通節點數據域};struct Node *next; //節點指針域 }Node,*Node_ptr;鏈表的函數 注意事項 1.創建節點時&#xff0c;需要初…

【第三節】Class與Style綁定

文章目錄Class與Style綁定綁定HTML Class對象語法數組語法綁定內聯樣式對象語法數組語法自動添加前綴Class與Style綁定 數據綁定一個常見需求是操作元素的 class 列表和它的內聯樣式,因為它們都是屬性&#xff0c;我們可以用 v-bind 處理它們:我們只需要計算出表達式最終的字符…

CMOS知識點 離子注入工藝

知識點8&#xff1a;離子注入是為了將摻雜劑&#xff08;如硼、磷等&#xff09;精確引入硅晶片的近表面區域&#xff0c;以改變其電學性質。工藝過程&#xff1a;電離與加速&#xff1a;摻雜劑原子在離子源中被電離&#xff08;帶電&#xff09;&#xff0c;通過高壓電場&…

從安裝到上手:Ubuntu 22.04 玩轉 Containerd 2.1.3 容器運行時

Containerd 是一款支持 OCI 規范的容器運行時&#xff0c;注重容器部署和生命周期管理的簡單性、健壯性與可移植性&#xff0c;常被嵌入到 Docker 和 Kubernetes 等系統中。本文將詳細介紹在 Ubuntu 22.04 服務器上通過二進制包手動安裝 Containerd 的完整步驟&#xff0c;包括…

Hadoop與云原生集成:彈性擴縮容與OSS存儲分離架構深度解析

Hadoop與云原生集成的必要性Hadoop在大數據領域的基石地位作為大數據處理領域的奠基性技術&#xff0c;Hadoop自2006年誕生以來已形成包含HDFS、YARN、MapReduce三大核心組件的完整生態體系。根據CSDN技術社區的分析報告&#xff0c;全球超過75%的《財富》500強企業仍在使用Had…