34.Socket編程(UDP)(上)

點分十進制字符串IP 轉 32位網絡序列IP

分析:1)IP轉成4字節? ? ? ? 2)4字節轉成網絡序列

思路:

  • "192.168.1.1" 進行字符串劃分,以 "." 為分割符,分割出"192","168","1","1"
  • 將這些字符串轉成8位的整型(字符),192,168,1,1
  • 網絡字節序是大端,高權值位放在低地址,定義一個32位整型(變量內字節地址是依次增大,取地址是最小地址),192放取地址的第一個字節,168第二個字節,以此類推。

或者用 inet_addr(),將ip點分十進制字符串傳入,返回值4字節網絡字節序。

接口使用

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);

  • sockfd:創建套接字打開的文件fd
  • buf:接受緩沖區
  • len:接受緩沖區大小
  • flags:0,表示阻塞式IO
  • src_addr:輸出型參數,用來獲取客戶端的套接字信息(IP和端口)
  • addrlen:先是輸入型參數,src_addr指向結構體大小,后是輸出型參數,實際讀到信息大小
  • 返回值:成功,返回接受到數據的字節數;失敗-1返回

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);

  • sockfd:創建套接字打開的文件fd
  • buf:發送緩沖區
  • len:發送緩沖區大小
  • flags:0,表示阻塞式IO
  • src_addr:輸入型參數,指定發給哪一個客戶端
  • addrlen:src_addr指向的結構體大小
  • 返回值:成功,發送的字節數;失敗-1返回,錯誤碼被設置

客戶端如何知道服務端IP和端口

客戶端和服務端是一家公司寫的,內置了服務端的IP和端口

本地環回(localhost, 127.0.0.1)

????????本地環回:要求客戶端和服務端必須在一臺機器上,表明我們是本地通信,client發送的數據,不會被推送到網絡,而是在OS內部,轉一圈直接交給對應的服務器端(經常用來進行網絡代碼的測試)

服務端bind時不顯式綁定IP

bind公網IP,不行的原因:公網IP沒有配置到IP上,同一主機綁定時,無法直接bind。

如果我們顯式進行地址綁定,client未來訪問時,就必須使用server綁定的信息。

為什么不建議手動綁定特定IP?

????????因為一臺主機可以有多個IP,綁定特定IP,只能接受該IP的數據,而發給其他本主機IP的數據接收不了。

做法:綁定IP時,值設置為?INADDR_ANY(任意IP地址bind,數值上為0)

客戶端不用顯式bind

  • client需不需要bind?需要bind
  • client需不需要顯式bind?不需要,首次發送消息OS會自動給client進行bind,OS知道IP,端口號采用隨機端口號的方式。(端口號是幾不重要,唯一就行了)
  • 原因:
    1. 一個端口號只能被一個進程所持有(端口號要找到唯一一個進程)
    2.未來有很多應用,端口號固定可能會導致沖突,無法bind,必須由OS隨機分配

UdpSocket編程V1(EchoServer)

Linux-remote: linux遠程倉庫

UdpServer.hpp

#pragma once#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <functional>
#include "Log.hpp"using namespace LogModule;#define BUFF_SIZE 1024
const int defaultfd = -1;class UdpServer
{using func_t = std::function<std::string(const std::string &)>;
public:UdpServer(uint16_t port, func_t func): _sockfd(defaultfd), _port(port), _isrunning(false), _func(func){// 1.創建套接字,(網絡類型,UDP協議)獲取網絡文件描述符_sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (_sockfd < 0){LOG(LogLevel::FATAL) << "socket error";exit(1);}LOG(LogLevel::INFO) << "socket success, sockfd: " << _sockfd;// 2.bind,綁定(通信類型,端口號port,IP)// 2.1 創建結構sockaddr_in, (man inet_addr),填充字段struct sockaddr_in peer;peer.sin_family = AF_INET;peer.sin_port = htons(_port);// 2.2 ip地址是一個結構,結構存放一個32位無符號整數// ip是一個字符串,192.168.1.1, 1.轉成數字 2.轉成網絡序列 -> inet_addr// peer.sin_addr.s_addr = inet_addr(_ip.c_str());peer.sin_addr.s_addr = INADDR_ANY; // 任意IP// 2.3 綁定int n = bind(_sockfd, (struct sockaddr *)&peer, sizeof(peer));if (n < 0){LOG(LogLevel::FATAL) << "bind error";exit(2);}LOG(LogLevel::INFO) << "bind success, sockfd: " << _sockfd;}void Start(){_isrunning = true;while (_isrunning){// 3.服務端收數據char buff[BUFF_SIZE];struct sockaddr_in peer;socklen_t addrlen = sizeof(struct sockaddr_in);ssize_t n = recvfrom(_sockfd, buff, BUFF_SIZE, 0,(struct sockaddr *)&peer, &addrlen);// 4.消息處理buff[n] = 0;std::string data = buff;LOG(LogLevel::INFO) << "client Says: " << data;std::string result = _func(data);// 5.服務端發送數據回客戶端ssize_t ret = sendto(_sockfd, result.c_str(), result.size(), 0, (const struct sockaddr *)&peer, addrlen);(void)ret;}}~UdpServer(){}private:int _sockfd;uint16_t _port;// std::string _ip;  //不需要,任意IPbool _isrunning;func_t _func;
};

UdpClient.cc

#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "Log.hpp"using namespace LogModule;// ./udpclient server_ip server_port
int main(int argc, char *argv[])
{if (argc != 3){std::cerr << "Usage: " << argv[0] << " server_ip server_port" << std::endl;return 1;}std::string ip = argv[1];uint16_t port = (uint16_t)(std::stoi(argv[2]));LOG(LogLevel::DEBUG) << "ip: " << ip << " port:" << port;// 1.創建socket,(網絡類型,UDP)int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0){LOG(LogLevel::FATAL) << "socket error";exit(1);}LOG(LogLevel::INFO) << "socket success, sockfd: " << sockfd;// 2.綁定參數,bind,不用顯式綁定。// 首次發送消息時由OS自動綁定,OS知道IP,端口號由OS隨機分配struct sockaddr_in peer;peer.sin_family = AF_INET;peer.sin_port = htons(port);peer.sin_addr.s_addr = inet_addr(ip.c_str());while (true){// 3.客戶端發數據// 3.1 從標準輸入按行讀數據std::cout << "Please Enter# ";std::string data;std::getline(std::cin, data);// 3.2 發送數據給服務端ssize_t ret = sendto(sockfd, data.c_str(), data.size(), 0, (struct sockaddr *)&peer, sizeof(peer));(void)ret;// 4.接受服務端處理過的數據char buff[1024];struct sockaddr_in sin;socklen_t len = sizeof(struct sockaddr_in);ssize_t n = recvfrom(sockfd, buff, 1024, 0, (struct sockaddr *)&sin, &len);// 5.使用數據buff[n] = 0;std::cout << "Server handlered, data: " << buff << std::endl;}return 0;
}

UdpServer.cc

#include "UdpServer.hpp"
#include <iostream>
#include <memory>std::string Hello(const std::string &data)
{std::string hello("Hello, ");hello += data;return hello;
}// ./udpserver port
int main(int argc, char *argv[])
{if (argc != 2){std::cerr << "Usage: " << argv[0] << " port" << std::endl;return 1;}uint16_t port = (uint16_t)std::stoi(argv[1]);std::unique_ptr<UdpServer> udpserver = std::make_unique<UdpServer>(port, Hello);udpserver->Start();return 0;
}

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

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

相關文章

Redis的持久化工具包—RDB AOF

文章目錄 前言 一、RDB 持久化&#xff08;快照持久化&#xff09; 1. 定義 2. RDB 觸發機制 &#xff08;1&#xff09;手動觸發 &#xff08;2&#xff09;自動觸發 3. RDB 持久化流程 4. RDB 核心配置 5. RDB 優缺點 二、AOF 持久化&#xff08;日志持久化&#xff09; 1. 定…

【Web安全】XXL-JOB框架SRC高頻漏洞分析總結

文章目錄前言一、核心漏洞分類與技術細節二、漏洞關聯利用與攻擊路徑三、版本演進與修復策略四、安全運維建議五、典型漏洞復現環境搭建六、總結前言 XXL-JOB是國內主流的開源分布式任務調度框架&#xff0c;由徐雪里開發維護&#xff0c;以輕量易用、高可用、適配分布式場景等…

Capacitor 打包后接口訪問不到的排查經歷

我最近在用 Quasar Capacitor 6 做一個 Android App&#xff0c;前端用的是 Vue3 Quasar&#xff0c;打包交給 Capacitor 去跑在手機的 WebView 里&#xff0c;后端是 FastAPI 提供接口。開發模式下一切順利&#xff0c;瀏覽器里訪問接口沒有任何問題&#xff0c;我甚至覺得打…

【正點原子】Linux應用編程入門~概念及環境介紹

應用編程概念 應用編程&#xff08;也可稱為系統編程&#xff09;與驅動編程、裸機編程有何不同&#xff1f;系統調用&#xff1b;何為庫函數&#xff1b;應用程序的 main()函數&#xff1b;應用程序開發環境的介紹&#xff1b;系統調用 定義系統調用&#xff08;system call&a…

一、HTML 完全指南:從零開始構建網頁

文章目錄前言一、 HTML 結構認識 HTML 標簽HTML 文件基本結構標簽層次結構快速生成代碼框架二、 HTML 常見標簽詳解2.1 注釋標簽2.2 標題標簽 (h1 - h6)2.3 段落標簽 (p)2.4 換行標簽 (br)2.5 格式化標簽2.6 圖片標簽 (img)2.7 超鏈接標簽 (a)2.8 表格標簽基本使用合并單元格2.…

基于POI-TL實現動態Word模板的數據填充:【散點圖】特殊處理方案

基于POI-TL實現動態Word模板的數據填充:散點圖特殊處理方案 在使用POI-TL進行Word模板動態數據填充時,圖表生成是一個常見需求。最近在項目中使用POI-TL處理散點圖時遇到了一個特殊問題,經過研究后找到了解決方案,特此記錄分享。 問題背景 POI-TL作為一款優秀的Java Wor…

使用node-Express框架寫一個學校宿舍管理系統練習項目-前后端分離

今天繼續分享一個新的練習項目&#xff0c;是使用node做為后端語言&#xff0c;來寫的一個前后端分離項目&#xff1a;學校宿舍管理系統。我們如果想掌握一門編程語言&#xff0c;就是需要大量的練習。所以當我們學習到了一些知識&#xff0c;自己想一下 可以拿學到的知識&…

Kafka 運維實戰基本操作含命令與最佳實踐

1. 基礎概覽與工具入口 Kafka 發行包的所有 CLI 工具均在 bin/ 目錄下。任何工具不帶參數運行都會顯示所有可用選項。本文命令默認&#xff1a;--bootstrap-server localhost:9092&#xff1b;生產請替換為你的控制面或內網 VIP。 2. 主題管理&#xff08;創建 / 修改 / 刪除 /…

貪心算法應用:航班起降問題詳解

Java中的貪心算法應用&#xff1a;航班起降問題詳解 貪心算法是一種在每一步選擇中都采取當前狀態下最優的選擇&#xff0c;從而希望導致全局最優解的算法策略。在航班起降問題中&#xff0c;貪心算法可以有效地解決機場跑道調度問題&#xff0c;即如何安排航班的起降順序以最大…

uniapp scroll-view 設置scrollTop無效

當我們使用 scroll-view的scroll-top的時候 默認想讓它回到頂部&#xff0c;當我們設置值為0的時候會不生效&#xff0c;在實際運用過程中&#xff0c;發現設置了scroll-top無效&#xff0c;滾動條位置并沒有發生變化&#xff0c;是因為微信小程序的官方框架處于性能考慮&#…

網絡與通信

1.TCP協議與UDP協議TCP&#xff08;Transmission Control Protocol&#xff0c;傳輸控制協議&#xff09;和 UDP&#xff08;User Datagram Protocol&#xff0c;用戶數據報協議&#xff09;是 TCP/IP 協議族中兩種核心的傳輸層協議&#xff0c;它們在數據傳輸方式、可靠性、適…

Node.js中package.json詳解

1. name&#xff08;名稱&#xff09; 如果你計劃發布你的包&#xff0c;package.json 中最重要的字段是 name 和 version&#xff0c;因為它們是必需的。name 和 version 共同組成一個假定完全唯一的標識符。包的更改應伴隨版本號的更新。如果你不打算發布包&#xff0c;那么…

代碼隨想錄第14天| 翻轉、對稱與深度

226.翻轉二叉樹 &#xff08;優先掌握遞歸&#xff09; 題目鏈接/文章講解/視頻講解&#xff1a;翻轉二叉樹 交換的是指針&#xff0c;而不是數值&#xff0c;如果用數值做交換&#xff0c;需要交換的節點下面無法很好的操作。 使用遞歸來實現&#xff0c;但要提前清除是什么順…

DNS-Windows上使用DNS

DNS-Windows上使用DNS一、查看與修改DNS配置1.1、查看當前DNS服務器設置1.2、臨時修改 DNS 服務器&#xff08;命令行&#xff09;二、DNS緩存相關操作2.1、查看DNS緩存內容2.2、 刷新 DNS 緩存&#xff08;清除過期記錄&#xff09;三、測試域名解析&#xff08;nslookup 工具…

3dsMax 2026 .NET Core 8 轉型下的Maxscript腳本開發:動態編譯模塊的重構策略與兼容性升級路徑

3ds Max 長期以來一直提供出色的 .NET 集成,使 Maxscript 能夠無縫利用任何 .NET 庫的強大功能。部分開發者在工具中廣泛使用了 .NET 功能。 之前,3ds Max 依賴于 .NET Framework 4.8 并且最近更新到了 4.8.1,用于 2025 版本的發布。然而,隨著 3ds Max 2026 的推出,Autod…

golang 做webrtc開發核心

在Golang中進行WebRTC開發&#xff0c;核心在于理解WebRTC協議的工作原理以及如何利用Go生態中的庫來實現關鍵功能。以下是Golang WebRTC開發的核心要點&#xff1a; WebRTC基礎概念 了解ICE&#xff08;Interactive Connectivity Establishment&#xff09;協議用于NAT穿越掌握…

RabbitMQ 異步化抗洪實戰

說明&#xff1a;本文僅展示架構思路與安全片段&#xff0c;所有敏感字段已用占位符&#xff1b;不含可直接復刻的生產細節。數據與接口均為演示/虛擬。0. 背景與目標長耗時/不確定接口&#xff08;如對接第三方機器人平臺&#xff09;的同步阻塞&#xff0c;容易造成請求堆積與…

接口返回 2 萬條數據,easy-trans導致多了20s耗時排查過程

內網訪問排版核料詳情功能&#xff0c;用戶反饋要等十幾秒排查 sql&#xff1a;sql 比較簡單排查內存計算&#xff1a;arthus trace 類名 方法名 總耗時2s排查頁面渲染是否緩慢&#xff1a;F12 查看接口 等待服務器響應 20s 下載時間 30s, 故不考慮渲染問題排查請求響應日志打…

AIGC入門,手搓大模型客戶端與MCP交互

概述 在現代應用開發中&#xff0c;將大語言模型&#xff08;LLM&#xff09;與專用工具服務相結合&#xff0c;可以構建出既能理解自然語言&#xff0c;又能準確執行專業任務的智能代理。本文介紹一個基于 MCP&#xff08;Model Context Protocol&#xff09;協議和 Ollama 本…

深度學習:從預備知識到未來展望

在當今數字化時代&#xff0c;深度學習正以前所未有的速度改變著我們的生活和工作方式。從智能語音助手到自動駕駛汽車&#xff0c;從精準醫療到個性化推薦系統&#xff0c;深度學習的應用無處不在。本文將從深度學習的預備知識入手&#xff0c;探討其發展歷程、關鍵技術和未來…