UDP網絡通信

UDP網絡通信:

步驟1 創建套接字:

#include <sys/types.h>        
#include <sys/socket.h>int socket(int domain, int type, int protocol);

參數一 domain:
AF_UNIX Local communication unix(7) 本地通信
AF_INET IPv4 Internet protocols ip(7) 網絡通信

參數二 type:
SOCK_DGRAM Supports datagrams (connectionless, unreliable messages of a fixed maximum length). 無連接不可靠面向數據報文,也就是UDP

參數三 protocol:
一般省略,直接為0.

RETURN VALUE
On success, a file descriptor for the new socket is returned. On error, -1 is returned, and errno is set appropriately.(成功返回一個文件描述符,失敗返回-1)。
在這里插入圖片描述

步驟2 綁定 將IP端口與套接字綁定起來:

綁定的過程,需要將IP和端口號關聯起來,使用 sockaddr_in 對信息進行關聯。
使用 sockaddr_in 需要頭文件 #include <netinet/in.h> 與 #include <arpa/inet.h>
需要將本體服務端的 IP 和 port 填充進 sockaddr_in 的結構體中。
結構體包含三個需要填充的字段:
1.sin_family : 通信的類型。這個和套接字選擇的類型要相同。
2.sin_port : 端口號,如果手動寫入的端口號是16位主機序列,不符合網絡序列,因此需要利用 htons(uint16_t) 將其轉換為網絡序列
3.sin_addr.s_addr : 網絡地址。傳入的肯定是一個字符串,但是網絡中需要的是4字節 IP,需要的是網絡序列的 IP,因此又需要轉換。其轉換函數為:inet_addr(string)。
在這里插入圖片描述
完成上述的填充工作后,bind函數可以將填充好的字段和套接字關聯起來。關聯如下:

#include <sys/types.h>        
#include <sys/socket.h>int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

RETURN VALUE
On success, zero is returned. On error, -1 is returned, and errno is set appropriately.(成功返回0,失敗-1)

這里的第二個參數是 struct sockaddr* ,而填充的時候用的是struct sockaddr_in,因此需要強轉如下。
在這里插入圖片描述
完整代碼如下:
在這里插入圖片描述

步驟三 使用函數讀寫數據。

UDP不能使用 read 和 write,
讀數據需要使用 recvfrom:
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
參數分別為:fd,緩沖區和緩沖區的大小(讀出的數據放在哪里,期望接受多少數據),flags設置為0表示為阻塞讀取。
后兩個參數為:輸入型參數,這兩個參數放的就是誰給我傳的網絡信息,放的就是對方的 IP 和 port。
返回值大于 0 讀取成功。后兩個參數的作用就是得到客戶端是誰。
recvfrom 的返回值就是接受了多少數據。

寫數據用的是 sendto:

#include <sys/types.h>
#include <sys/socket.h>
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);

后兩個參數為輸入型參數,分別為:
const struct sockaddr *dest_addr:代表客戶端。
socklen_t addrlen:代表客戶端的長度。
RETURN VALUE
On success, these calls return the number of bytes sent. On error, -1 is returned, and errno is set appropriately.(成功返回值大于0,失敗-1)

客戶端讀數據,recvfrom的后兩個參數直接給一個初始的無意義的參數給上就行。

網絡轉主機和主機轉網絡序列。
在這里插入圖片描述
在這里插入圖片描述

代碼如下:

//udpserver.hpp
#pragma once#include <iostream>
#include <cstring>
#include <unistd.h>
#include <string>
#include "nocopy.hpp"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>static const int gsockfd = -1;
static const uint16_t glocalport = 8888;
enum{SOCKET_ERROR = 1,BIND_ERROR,
};// UdpServer user("192.1.1.1", 8888)
class UdpServer : public nocopy
{
public:UdpServer(const std::string& localip, uint16_t localport = glocalport):_sockfd(gsockfd), _localport(localport),_localip(localip),_isrunning(false){}void InitServer(){//1 創建套接字_sockfd = ::socket(AF_INET, SOCK_DGRAM, 0);if(_sockfd < 0){std::cout << "socket error! " << std::endl;exit(SOCKET_ERROR);}std::cout << "socket success, _sockfd: %d " << _sockfd << std::endl; //預計是 3//2 綁定struct sockaddr_in local;memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_port = htons(_localport);local.sin_addr.s_addr = inet_addr(_localip.c_str());int n = ::bind(_sockfd, (struct sockaddr*)&local, sizeof(local));if(n<0){std::cout << "bind error! " << std::endl;exit(BIND_ERROR);}std::cout << "bind success" << std::endl;}void Start(){_isrunning = true;char inbuffer[1024];while(_isrunning){struct sockaddr peer;socklen_t len = sizeof(peer);ssize_t n = recvfrom(_sockfd, &inbuffer, sizeof(inbuffer)-1, 0, (struct sockaddr*)&peer, &len);if(n > 0){inbuffer[n] = 0;std::cout << "clint say# " << inbuffer << std::endl;std::string echo_string = "[udp_server echo] #";echo_string += inbuffer;sendto(_sockfd, echo_string.c_str(), echo_string.size(), 0, (struct sockaddr*)&peer, len);}}}~UdpServer(){if(_sockfd > gsockfd) ::close(_sockfd);}private:int _sockfd;uint16_t _localport;std::string _localip;bool _isrunning;
};
//udpserver.cc
#include "UdpServer.hpp"
#include  <memory>int main()
{uint16_t port = 8899;std::string ip = "0";std::unique_ptr<UdpServer> user = std::make_unique<UdpServer>(ip, port);user->InitServer();user->Start();return 0;
}
//udpclient.cc#include <iostream>
#include <unistd.h>
#include <string>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>// 客戶端得知道服務器的 IP 地址和端口號才能操作
// 因此,在調用客戶端的時候,可以附上服務端的IP和port。
int main(int argc, char* argv[])
{if(argc != 3){std::cerr <<"Usage: " << argv[0] << "server-ip server-port " << std::endl;exit(0);}//拿到服務器的IP和端口std::string serverip = argv[1];uint16_t serverport = std::stoi(argv[2]);//1 創建套接字int sockfd = ::socket(AF_INET, SOCK_DGRAM, 0);if(sockfd < 0){std::cerr << "client socket error!"<< std::endl;exit(1);}//2 bind 綁定客戶端的IP和端口// client的端口不會被用戶去設定,而是OS去隨機選擇端口struct sockaddr_in server;memset(&server, 0, sizeof(server));server.sin_family = AF_INET;server.sin_port = htons(serverport);server.sin_addr.s_addr = inet_addr(serverip.c_str());while(1){std::string line;std::cout << "Please Enter: ";std::getline(std::cin, line);int n = sendto(sockfd, line.c_str(), line.size(), 0, (struct sockaddr*)&server, sizeof(server));if(n > 0){struct sockaddr_in temp;socklen_t len = sizeof(temp);char buffer[1024];int m = recvfrom(sockfd, &buffer, sizeof(buffer)-1, 0, (struct sockaddr*)&temp, &len);if(m>0){buffer[m] = 0;std::cout << buffer << std::endl;}else{std::cout << "recvfrom error" << std::endl;break;}}else{break;}}::close(sockfd);return 0;
}

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

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

相關文章

教你快速理解linux中的NUMA節點探測是干什么用的?

想象一個大城市被劃分成幾個區&#xff08;比如東區、西區&#xff09;。每個區有自己的超市&#xff08;內存&#xff09;&#xff0c;居民&#xff08;CPU&#xff09;去本區的超市買東西最快&#xff0c;去其他區的超市會慢一些。 NUMA節點探測&#xff0c;就是Linux系統在…

使用 Less 實現 PC 和移動端樣式適配

&#x1f310; 使用 Less 實現 PC 和移動端樣式適配 —— 以 position 屬性為例 在前端開發中&#xff0c;我們常常會遇到這樣一個場景&#xff1a; 在 PC 頁面中需要某個元素是 position: relative;&#xff0c;但在移動端卻希望它是 position: inherit;&#xff0c;以便更靈…

企業戰略管理(設計與工程師類)-2-戰略規劃及管理過程-1-概述

戰略管理過程 參考資料&#xff1a; 戰略管理 - 清華大學- 蔡臨寧公司戰略與風險管理 - 華中科技大學 - 賀遠瓊戰略管理 - 北京理工大學 - 楊萬榮DeepSeek - 深度思考與聯網檢索 AFI框架 戰略管理最典型的就是采用傳統的AFI通用戰略管理框架&#xff08;模型&#xff09;&a…

Swoole 的 Hyperf 框架和 Go 的 Gin 框架高并發原理以及技術實現對比分析

Swoole 的 Hyperf 框架和 Go 的 Gin 框架雖然都支持高并發&#xff0c;但它們的實現原理、底層機制和適用場景有顯著差異。以下從 高并發原理、技術實現區別、優缺點 三個方面詳細分析&#xff1a; 一、高并發實現原理 1. Hyperf (PHP Swoole) Hyperf 的高并發能力基于 Swoo…

【教程】如何利用bbbrisk一步一步實現評分卡

利用bbbrisk一步一步實現評分卡 一、什么是評分卡1.1.什么是評分卡1.2.評分卡有哪些 二、評分卡怎么弄出來的2.1.如何制作評分卡2.2.制作評分卡的流程 三、變量的分箱3.1.數據介紹3.2.變量自動分箱3.3.變量的篩選 四、構建評分卡4.1.評分卡實現代碼4.2.評分卡表4.3.閾值表與分數…

AI日報 - 2025年4月2日

&#x1f31f; 今日概覽&#xff08;60秒速覽&#xff09; ▎&#x1f916; AGI突破 | 研究揭示零RL訓練可誘發模型頓悟&#xff0c;Anthropic發布Claude 3.5內部機制研究&#xff0c;簡化語言模型推理優化新方法提出。 DeepSeek-R1無需額外指令即可深度推理&#xff1b;Anthro…

探索 Kubernetes 網絡穿透:如何從外部訪問 K8s Pod 地址

文章目錄 探索 Kubernetes 網絡穿透&#xff1a;如何從外部訪問 K8s Pod 地址為什么需要外部訪問 Pod 地址&#xff1f;常見的網絡穿透方案NodePortLoadBalancerIngressPort-ForwardHostNetworkkt-connect&#xff1a;為開發調試提供便捷穿透 實踐建議與注意事項各方案對比表總…

深入理解 Apache Dagster:數據管道編排實戰指南

本文系統介紹了 Apache Dagster 的核心概念與實踐方法&#xff0c;涵蓋環境搭建、管道定義、運行調試及高級功能&#xff0c;幫助開發者快速掌握這一現代化數據編排工具&#xff0c;提升數據工程效率。 1. 背景與核心優勢 隨著數據驅動應用的復雜化&#xff0c;傳統工具在可維…

Minio集群部署

Minio集群部署 資源規劃 IP服務規劃配置192.168.116.138minio-116核32G磁盤10T192.168.116.139minio-216核32G磁盤10T192.168.116.140minio-316核32G磁盤10T192.168.116.141minio-416核32G磁盤10T192.168.116.128nginx代理8核16G磁盤500G 基本環境配置 下面命令minio4臺設備…

操作系統高頻(六)linux內核

操作系統高頻&#xff08;六&#xff09;linux內核 1.內核態&#xff0c;用戶態的區別??? 內核態和用戶態的區別主要在于權限和安全性。 權限&#xff1a;內核態擁有最高的權限&#xff0c;可以訪問和執行所有的系統指令和資源&#xff0c;而用戶態的權限相對較低&#x…

強大而易用的JSON在線處理工具

強大而易用的JSON在線處理工具&#xff1a;程序員的得力助手 在當今的軟件開發世界中&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;已經成為了數據交換的通用語言。無論是前端還是后端開發&#xff0c;我們都經常需要處理、驗證和轉換JSON數據。今天&a…

【學習記錄】pytorch載入模型的部分參數

需要從PointNet網絡框架中提取encoder部分的參數&#xff0c;然后賦予自己的模型。因此&#xff0c;需要從一個已有的.pth文件讀取部分參數&#xff0c;加載到自定義模型上面。做了一些嘗試&#xff0c;記錄如下。 關于模型保存與載入 torch.save(): 使用Python的pickle實用程…

【藍橋杯14天沖刺課題單】Day 8

1.題目鏈接&#xff1a;19714 數字詩意 這道題是一道數學題。 先考慮奇數&#xff0c;已知奇數都可以表示為兩個相鄰的數字之和&#xff0c;2k1k(k1) &#xff0c;那么所有的奇數都不會被計入。 那么就需要考慮偶數什么情況需要被統計。根據打表&#xff0c;其實可以發現除了…

鴻蒙ArkTS開發:微信/系統來電通話監聽功能實現

本文將介紹如何在鴻蒙應用中使用ArkTS實現通話監聽和錄音功能&#xff0c;利用harmony-utils工具庫簡化開發流程。 工具庫地址 一、功能概述 本實現包含以下核心功能&#xff1a; 通話狀態監聽&#xff1a;檢測來電、去電和通話中狀態 音頻流監控&#xff1a;通過麥克風使用…

NFS 重傳次數速率監控

這張圖展示的是 NFS 重傳次數速率監控&#xff0c;具體解釋如下&#xff1a; 1. 指標含義 監控指標 node_nfs_rpc_retransmissions_total 統計 NFS&#xff08;網絡文件系統&#xff09;通信中 RPC&#xff08;遠程過程調用&#xff09;的重傳次數&#xff0c;rate(node_nfs_…

【 <二> 丹方改良:Spring 時代的 JavaWeb】之 Spring Boot 中的國際化:支持多語言的 RESTful API

<前文回顧> 點擊此處查看 合集 https://blog.csdn.net/foyodesigner/category_12907601.html?fromshareblogcolumn&sharetypeblogcolumn&sharerId12907601&sharereferPC&sharesourceFoyoDesigner&sharefromfrom_link <今日更新> 一、開篇整…

黑帽SEO之搜索引擎劫持-域名劫持原理分析

問題起源 這是在《Web安全深度剖析》的第二章“深入HTTP請求流程”的2.3章節“黑帽SEO之搜索引擎劫持”提到的內容&#xff0c;但是書中描述并不詳細&#xff0c;沒有講如何攻擊達到域名劫持的效果。 書中對SEO搜索引擎劫持的現象描述如下&#xff1a;直接輸入網站的域名可以進…

theos工具來編譯xcode的swiftUI項目為ipa文件

Theos 是一個開源的開發工具套件&#xff0c;主要用于為 iOS/macOS 平臺開發和編譯 越獄插件&#xff08;Tweaks&#xff09;、動態庫、命令行工具等。它由 Dustin Howett 創建&#xff0c;并被廣泛用于越獄社區的開發中。但這里我主要使用它的打包ipa功能&#xff0c;因為我的…

25.4.1學習總結【Java】

動態規劃題 2140. 解決智力問題https://leetcode.cn/problems/solving-questions-with-brainpower/ 給你一個下標從 0 開始的二維整數數組 questions &#xff0c;其中 questions[i] [pointsi, brainpoweri] 。 這個數組表示一場考試里的一系列題目&#xff0c;你需要 按順…

計算機網絡知識點匯總與復習——(二)物理層

Preface 計算機網絡是考研408基礎綜合中的一門課程&#xff0c;它的重要性不言而喻。然而&#xff0c;計算機網絡的知識體系龐大且復雜&#xff0c;各類概念、協議和技術相互關聯&#xff0c;讓人在學習時容易迷失方向。在進行復習時&#xff0c;面對龐雜的的知識點&#xff0c…