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.mzph.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…