基于UDP的套接字通信

udp是一個面向無連接的,不安全的,報式傳輸層協議,udp的通信過程默認也是阻塞的。使用UDP進行通信,服務器和客戶端的處理步驟比TCP要簡單很多,并且兩端是對等的 (通信的處理流程幾乎是一樣的),也就是說并沒有嚴格意義上的客戶端和服務器端。

UDP通信不需要建立連接 ,因此不需要進行connect()操作,在通信過程中,每次都需要指定數據接收端的IP和端口。UDP不對收到的數據進行排序,在UDP報文的首部中并沒有關于數據順序的信息。
UDP對接收到的數據報不回復確認信息,發送端不知道數據是否被正確接收,也不會重發數據。如果發生了數據丟失,不存在丟一半的情況,如果丟當前這個數據包就全部丟失了?

UDP通信過程雖然默認還是阻塞的,但是通信函數和TCP不同,操作函數原型如下:

// 接收數據, 如果沒有數據,該函數阻塞
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);

參數:

  • sockfd: 基于udp的通信的文件描述符
  • buf: 指針指向的地址用來存儲接收的數據
  • len: buf指針指向的內存的容量, 最多能存儲多少字節
  • flags: 設置套接字屬性,一般使用默認屬性,指定為0即可
  • src_addr: 發送數據的一端的地址信息,IP和端口都存儲在這里邊, 是大端存儲的,如果這個參數中的信息對當前業務處理沒有用處, 可以指定為NULL, 不保存這些信息
  • addrlen: 類似于accept() 函數的最后一個參數, 是一個傳入傳出參數,傳入的是src_addr參數指向的內存的大小, 傳出的也是這塊內存的大小。如果src_addr參數指定為NULL, 這個參數也指定為NULL即可
  • 返回值:成功返回接收的字節數,失敗返回-1
// 發送數據函數
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);

參數:

  • sockfd: 基于udp的通信的文件描述符
  • buf: 這個指針指向的內存中存儲了要發送的數據
  • len: 要發送的數據的實際長度
  • flags: 設置套接字屬性,一般使用默認屬性,指定為0即可
  • dest_addr: 接收數據的一端對應的地址信息, 大端的IP和端口
  • addrlen: 參數 dest_addr 指向的內存大小
  • 返回值:函數調用成功返回實際發送的字節數,調用失敗返回-1?

服務端代碼示例:

在UDP通信過程中,服務器和客戶端都可以作為數據的發送端和數據接收端,假設服務器端是被動接收數據,客戶端是主動發送數據,那么在服務器端就必須綁定固定的端口了。

#include <iostream>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>int main() {int fd = socket(AF_INET, SOCK_DGRAM, 0);if (fd == -1) {perror("socket");return -1;}// 初始化服務器地址sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(9999);  server_addr.sin_addr.s_addr = INADDR_ANY;if (bind(fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {perror("bind failed");exit(EXIT_FAILURE);
}char buffer[8888];sockaddr_in client_addr;socklen_t client_addr_len = sizeof(client_addr);while (1) {// 接收客戶端數據ssize_t recv_len = recvfrom(fd, buffer, sizeof(buffer)-1, 0,(struct sockaddr*)&client_addr,&client_addr_len);if (recv_len == -1) {perror("recvfrom failed");continue;}buffer[recv_len] = '\0';  // 確保字符串終止// 打印客戶端信息char client_ip[INET_ADDRSTRLEN];inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, INET_ADDRSTRLEN);std::cout << "Client (" << client_ip << ":" << ntohs(client_addr.sin_port) << "): " << buffer << std::endl;// 構造響應(添加前綴)char prefix[] = "server say:";char response[sizeof(buffer)];sprintf(response, "%s%s", prefix, buffer);// 發送響應(使用正確的長度)ssize_t send_len = sendto(fd, response, strlen(response), 0,(const struct sockaddr*)&client_addr,client_addr_len);if (send_len == -1) {perror("sendto failed");continue;}}close(fd);return 0;
}

作為數據接收端,服務器端通過bind()函數綁定了固定的端口,然后基于這個固定的端口通過recvfrom()函數接收客戶端發送的數據,同時通過這個函數也得到了數據發送端的地址信息(recvfrom的第三個參數),這樣就可以通過得到的地址信息通過sendto()函數給客戶端回復數據了。

客戶端代碼示例:

#include <iostream>
#include <arpa/inet.h>
#include <string>
#include <unistd.h>
#include <pthread.h>  int main() {int fd = socket(AF_INET, SOCK_DGRAM, 0);if (fd == -1) {perror("socket");return -1;}// 初始化服務器地址sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(9999);  inet_pton(AF_INET, "192.168.175.130", &server_addr.sin_addr);  int num = 0;std::string t = std::to_string(pthread_self());std::string s = ":Hello World!!!";while (1) {std::string S = t + s + std::to_string(++num);// 發送數據到服務器ssize_t send_len = sendto(fd, S.data(), S.size(), 0,(const struct sockaddr*)&server_addr,sizeof(server_addr));if (send_len == -1) {perror("sendto failed");continue;}// 接收服務器響應sockaddr_in server_response_addr;socklen_t addr_len = sizeof(server_response_addr);char buffer[1024] = {0};ssize_t recv_len = recvfrom(fd, buffer, sizeof(buffer)-1, 0,(struct sockaddr*)&server_response_addr,&addr_len);if (recv_len == -1) {perror("recvfrom failed");continue;}// 打印服務器地址和響應char str[INET_ADDRSTRLEN];std::cout << "Server (" << inet_ntop(AF_INET, &server_response_addr.sin_addr, str, INET_ADDRSTRLEN)<< ":" << ntohs(server_response_addr.sin_port) << "): " << buffer << std::endl;sleep(1);}close(fd);return 0;
}

作為數據發送端,客戶端不需要綁定固定端口,客戶端使用的端口是隨機綁定的(也可以調用bind()函數手動進行綁定)。

同時開啟三個客戶端一個服務端運行結果:

?

UDP是一種無連接的傳輸層協議,其特性天然支持多客戶端同時通信,服務器不需要與每個客戶端建立持久連接,只需接收來自不同源地址的數據包,每個客戶端發送的 UDP 數據包都是獨立的,服務器可以逐個處理,每個數據包都包含發送方的 IP 和端口信息,服務器可以據此區分不同客戶端。

所以可以啟動多個客戶端與服務器進行通信,UDP 協議的特性會確保每個客戶端的請求被正確路由和處理。

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

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

相關文章

華為CE交換機抓包

capture-packet interface 100GE1/0/5 destination file 001.cap packet-len 64 注&#xff1a;早期版本&#xff08;disp device&#xff09;可能在系統視圖下&#xff08;sys&#xff09; 抓完包后可以看到對應文件&#xff08;早期版本在根目錄下&#xff09;&#xff1a;…

Python 數據分析與可視化 Day 3 - Pandas 數據篩選與排序操作

&#x1f3af; 今日目標 掌握 DataFrame 的條件篩選&#xff08;布爾索引&#xff09;學會多條件篩選、邏輯運算熟練使用排序&#xff08;sort_values&#xff09;提升數據組織力結合列選擇進行數據提取分析 &#x1f9ea; 一、列選擇與基本篩選 ? 選擇單列 / 多列 df[&quo…

Vite項目初始化與配置

下面,我們來系統的梳理關于 Vite 項目初始化與配置 的基本知識點: 一、Vite 核心概念與優勢 1.1 什么是 Vite? Vite(法語意為 “快速”)是新一代的前端構建工具,由 Vue.js 作者尤雨溪開發。它解決了傳統構建工具(如 Webpack)在開發環境中的性能瓶頸問題。 1.2 Vite …

Transformer中的核心問題 知識點匯總

Transformer架構圖 transformer整體架構 1. Transformer 的參數配置 Transformer 的Encoder層和Decoder層都使用6個注意力模塊&#xff0c;所有的子網絡的輸出維度均為512維&#xff0c;多頭注意力部分使用了8個注意力頭。 2. 歸一化的方式 歸一化的方式為LayerNorm&#xff0c…

python web開發-Flask數據庫集成

Flask 數據庫集成完全指南&#xff1a;Flask-SQLAlchemy 實踐 1. 引言 數據庫是現代Web應用的核心組件&#xff0c;Flask通過Flask-SQLAlchemy擴展提供了強大的數據庫集成能力。本文將全面介紹如何在Flask應用中使用Flask-SQLAlchemy進行數據庫操作&#xff0c;涵蓋從基礎配置…

一站式用AI編程神奇Cursor/Trae(VScode環境)開發運行Scala應用

平時開發時&#xff0c;我們常用 IDEA 搭配 Scala 來開發 Spark 或 Flink 等大數據應用。但如今像 Cursor 這樣的編程神器層出不窮&#xff0c;它們只支持 VSCode。要是 Scala 應用能在 VSCode 環境下便捷運行&#xff0c;我們就無需在 VSCode 開發、卻在 IDEA 運行&#xff0c…

【Django開發】django美多商城項目完整開發4.0第2篇:項目準備,配置【附代碼文檔】

教程總體簡介&#xff1a;美多商城 商業模式介紹 1.B2B--企業對企業 2.C2C--個人對個人 5.O2O--線上到線下 開發流程 說明&#xff1a; 需求分析 1. 用戶部分 注冊 登錄 個人信息 地址管理 修改密碼 3. 購物車部分 購物車管理 項目架構 創建工程 1. 在git平臺創建工程 2. 添加前…

基于 OpenCV 的圖像亮度、對比度與銳度調節

圖像亮度、對比度和銳度是圖像質量感知的重要參數&#xff0c;調節這些屬性常用于圖像增強、圖像美化或圖像分析的預處理階段。本文將基于 OpenCV 實現這三項基礎圖像處理功能&#xff0c;并提供滑動條交互界面與直方圖可視化分析&#xff0c;方便調試和理解效果。 亮度調整 圖…

WAF(web應用防火墻)的簡單了解

WAF稱之為Web應用防火墻&#xff0c;是一種專門設計用于保護web應用程序免受惡意攻擊的安全設備&#xff0c;能實時監控過濾和攔截可能對網站造成危害的網絡流量&#xff0c;從而避免網絡服務器被惡意入侵導致性能異常、數據泄露、服務中斷這些問題 (WAF是通過執行一系列針對HT…

跟著AI學習C# Day28

&#x1f4c5; Day 28&#xff1a;C# 源生成器&#xff08;Source Generators&#xff09;與編譯時元編程 ? 學習目標&#xff1a; 理解什么是 源生成器&#xff08;Source Generator&#xff09;&#xff1b;掌握如何在 編譯階段生成 C# 代碼&#xff0c;而不是運行時動態處…

設計模式精講 Day 4:建造者模式(Builder Pattern)

【設計模式精講 Day 4】建造者模式&#xff08;Builder Pattern&#xff09; 文章簡述&#xff1a; 在軟件開發中&#xff0c;對象的構造過程往往復雜且容易出錯&#xff0c;尤其是在對象包含多個可選參數或構建步驟時。建造者模式&#xff08;Builder Pattern&#xff09;正是…

如何輕松地將聯系人從 iPhone 轉移到 iPhone?

也許您升級到最新的 iPhone 型號&#xff0c;或者需要切換到另一部 iPhone 來工作。無論如何&#xff0c;您不能錯過您的聯系人&#xff0c;這對每個人來說都是最重要的數據。因此&#xff0c;今天我們將分享 5 種如何將聯系人從 iPhone 轉移到 iPhone 的方法&#xff0c;幫助您…

【51單片機簡單的流水燈程序問題】2022-5-24

1.利用單片機的P2口接8個發光二極管。簡單的流水燈程序問題-編程語言-CSDN問答 2&#xff0e;發光二極管自由閃爍&#xff08;自己設計兩種模式&#xff09;。 3&#xff0e;可通過按鍵實現暫停、啟動以及不用模式的切換。 4. 利用Proteus繪制電路原理圖 5. 元件選型&#xff1…

第七節:Vben Admin 最新 v5.0 (vben5) 快速入門 - 用戶管理(上)

Vben5 系列文章目錄 ?? 基礎篇 ? 第一節:Vben Admin 最新 v5.0 (vben5) 快速入門 ? 第二節:Vben Admin 最新 v5.0 (vben5) 快速入門 - Python Flask 后端開發詳解(附源碼) ? 第三節:Vben Admin 最新 v5.0 (vben5) 快速入門 - 對接后端登錄接口(上) ? 第四節:Vben Ad…

1572. 矩陣對角線元素的和

給你一個正方形矩陣 mat&#xff0c;請你返回矩陣對角線元素的和。 請你返回在矩陣主對角線上的元素和副對角線上且不在主對角線上元素的和。 示例 1&#xff1a; 輸入&#xff1a;mat [[1,2,3],[4,5,6],[7,8,9]] 輸出&#xff1a;25 解釋&#xff1a;對角線的和為&#xf…

供應鏈場景使用ClickHouse最佳實踐

一、概述 ClickHouse是一款由俄羅斯公司Yandex開發的開源列式數據庫管理系統&#xff0c;以其高性能的分析查詢能力和高壓縮比著稱。供應鏈場景中&#xff0c;數據量大且數據類型復雜&#xff0c;需要高效的數據存儲和快速的查詢性能&#xff0c;ClickHouse在這些方面具有顯著…

RA4M2開發IOT(0)----安裝e2 studio

RA4M2開發IOT.0--安裝e studio 概述視頻教學樣品申請安裝 概述 瑞薩電子靈活配置軟件包 (FSP) 是用于嵌入式系統設計的高質量增強型軟件包&#xff0c;支持瑞薩電子 RA 產品家族 Arm 微控制器&#xff0c;提供用戶友好的界面且可靈活擴展&#xff0c;確保從入門級到高性能的整…

【Ambari3.0.0 部署】Step2—免密登陸認證-適用于el8

如果有其他系統部署需求可以參考原文 戳我->所有組件編譯教程 戳我->獲取部署源代碼 一、免密登錄認證 &#x1f510; 在多臺服務器協同工作的環境中&#xff0c;免密登錄&#xff08;SSH 免密認證&#xff09;是一種常見的優化手段&#xff0c;能夠極大地提升運維效率&…

網站自助廣告投放系統源碼 附安裝教程(源碼下載)

網站自助廣告投放系統源碼 全自動無人化出售網站廣告位 站長必備 源碼測試可用&#xff0c;部分加密。感興趣自行下載 源碼下載&#xff1a;https://download.csdn.net/download/m0_66047725/91093092 更多資源下載&#xff1a;關注我 圖片&#xff1a;

日常運維問題匯總-15

42.SD開票計劃產生的預收款在正式開票時未自動清賬 統馭科目&#xff08;應收、預收&#xff09;對應的字段狀態組中附加科目設置銷售訂單字段設置為了隱藏導致&#xff0c;更改為“可選輸入項” 43.MIGO取消憑證時&#xff0c;用戶反饋發現除一行外&#xff0c;其它都不能取消…