Linux下使用C/C++进行UDP网络编程
UDP 是User Datagram Protocol 的简称,中文名是用户数据报协议,是一种无连接、不可靠的协议,同样它也是工作在传顺层。它只是简单地实现从一端主机到另一端主机的数据传输功能,这些数据通过 IP 层发送,在网络中传输,到达目标主机的顺序是无法预知的,因此需要应用程序对这些数据进行排序处理,这就带来了很大的不方便,此外,UDP 协议更没有流量控制、拥塞控制等功能,在发送的一端,UDP 只是把上层应用的数据封装到UDP 报文中,在差错检测方面,仅仅是对数据进行了简单的校验,然后将其封装到 IP 数据报中发送出去。而在接收端,无论是否收到数据,它都不会产生一个应答发送给源主机,并且如果接收到数据发送校验错误,那么接收端就会丢弃该UDP 报文,也不会告诉源主机,这样子传输的数据是无法保障其准确性的,如果想要其准确性,那么就需要应用程序来保障了。
UDP 协议的特点:
- 无连接、不可靠;
- 尽可能提供交付数据服务,出现差错直接丢弃,无反馈;
- 面向报文,发送方的UDP 拿到上层数据直接添加个UDP 首部,然后进行校验后就递交给 IP 层而接收的一方在接收到UDP 报文后简单进行校验,然后直接去除数据递交给上层应用;
- 速度快,因为UDP 协议没有TCP 协议的握手、确认、窗口、重传、拥塞控制等机制,UDP 是一个无状态的传输协议,所以它在传递数据时非常快,即使在网络拥塞的时候UDP 也不会降低发送的数据。 UDP 虽然有很多缺点,但也有自己的优点,所以它也有很多的应用场合,因为在如今的网络环境下, UDP 协议传输出现错误的概率是很小的,并且它的实时性是非常好,常用于实时视频的传输,比如直播、网络电话等,因为即使是出现了数据丢失的情况,导致视频卡帧,这也不是什么大不了的事情,所以,UDP协议还是会被应用与对传输速度有要求,并且可以容忍出现差错的数据传输中。
在Linux使用socket网络编程实现udp通信流程如下:
1. 初始化socket
int sock_fd = socket(AF_INET , SOCK_DGRAM , 0);
if(sock_fd < 0){perror("failed to open socket");return -1;
}
2. 绑定IP和端口号
/** 绑定IP和端口号 */
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY; // 本地任意IP
server_addr.sin_port = htons(8888); // 指定端口号
int ret = bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if(ret < 0)
{perror("failed to bind");close(sock_fd);return -1;
}
3. 设置组播接收(可选)
std::string multi_addr = "224.0.0.10";
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(multi_addr.c_str());
mreq.imr_interface.s_addr = INADDR_ANY;
ret = setsockopt(sock_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(struct ip_mreq));
if (0 >ret)
{perror("set socket multicast error");return false;
}
4. 设置接收超时(可选)
/** 设置接收超时(可选) */
int mill_sec = 2000; // 毫秒
struct timeval time_out;
time_out.tv_sec = mill_sec / 1000;
time_out.tv_usec = (mill_sec- time_out.tv_sec * 1000) * 1000;
ret = setsockopt(sock_fd, SOL_SOCKET,SO_RCVTIMEO,&time_out,sizeof (timeval));
if(ret < 0)
{perror("udp setTimeOut error!");
}
5. 发送数据
unsigned char buf[1024];
std::string ip = "192.168.1.10";
int port = 1234;
struct sockaddr_in client{};
memset(&client, 0, sizeof(client));
client.sin_addr.s_addr = inet_addr(ip.c_str());
client.sin_family = AF_INET;
client.sin_port = htons(port);
ret = sendto(sock_fd, buf, sizeof(buf), 0, reinterpret_cast<struct sockaddr *>(&client), sizeof(struct sockaddr));
if(ret < 0){perror("udpServer send error!");
}else{std::cout << "send success!" << std::endl;
}
6. 接收数据
unsigned char buffer[1024];
struct sockaddr_in addr;
socklen_t addr_len = sizeof(addr);
while(true)
{memset(buffer, 0, sizeof(buffer));ssize_t len = recvfrom(sock_fd_, buffer, sizeof(buffer), 0, reinterpret_cast<struct sockaddr *>(&addr), &addr_len);if(len > 0){std::cout << "received message len : " << len << std::endl;}else{perror("recv error");}
}
7. 完整代码
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netdb.h>
#include <net/if.h>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <iostream>
#include <cstring>
#include <thread>void recv_func(int sock_fd_)
{
unsigned char buffer[1024];
struct sockaddr_in addr;
socklen_t addr_len = sizeof(addr);
while(true)
{memset(buffer, 0, sizeof(buffer));ssize_t len = recvfrom(sock_fd_, buffer, sizeof(buffer), 0, reinterpret_cast<struct sockaddr *>(&addr), &addr_len);if(len > 0){std::cout << "received message len : " << len << std::endl;}else{perror("recv error");}
}
}int main(int agrc, char** argv)
{int sock_fd = socket(AF_INET , SOCK_DGRAM , 0); if(sock_fd < 0){perror("failed to open socket");return -1;}/** 绑定IP和端口号 */ struct sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = INADDR_ANY; // 本地任意IPserver_addr.sin_port = htons(8888); // 指定端口号int ret = bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));if(ret < 0){perror("failed to bind");close(sock_fd);return -1;}/** 设置组播接收 (可选)*/
std::string multi_addr = "224.0.0.10";
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(multi_addr.c_str());
mreq.imr_interface.s_addr = INADDR_ANY;
ret = setsockopt(sock_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(struct ip_mreq));
if (0 >ret)
{perror("set socket multicast error");return false;
}/** 设置接收超时(可选) */
int mill_sec = 2000; // 毫秒
struct timeval time_out;
time_out.tv_sec = mill_sec / 1000;
time_out.tv_usec = (mill_sec- time_out.tv_sec * 1000) * 1000;
ret = setsockopt(sock_fd, SOL_SOCKET,SO_RCVTIMEO,&time_out,sizeof (timeval));
if(ret < 0)
{perror("udp setTimeOut error!");
}/** 开启线程接收 */std::thread recv_t(recv_func, sock_fd);recv_t.detach();/** 主线程发送 */while (true){
unsigned char buf[1024];
std::string ip = "192.168.1.10";
int port = 1234;
struct sockaddr_in client{};
memset(&client, 0, sizeof(client));
client.sin_addr.s_addr = inet_addr(ip.c_str());
client.sin_family = AF_INET;
client.sin_port = htons(port);
ret = sendto(sock_fd, buf, sizeof(buf), 0, reinterpret_cast<struct sockaddr *>(&client), sizeof(struct sockaddr));
if(ret < 0){perror("udpServer send error!");
}else{std::cout << "send success!" << std::endl;
}usleep(50*1000);}
}
8. 编译运行
# 编译
g++ udp_main.cpp -o main -lpthread
# 运行
./main
相关文章:
Linux下使用C/C++进行UDP网络编程
UDP 是User Datagram Protocol 的简称,中文名是用户数据报协议,是一种无连接、不可靠的协议,同样它也是工作在传顺层。它只是简单地实现从一端主机到另一端主机的数据传输功能,这些数据通过 IP 层发送,在网络中传输&am…...
【JavaEE初阶】网络原理—关于TCP协议值滑动窗口与流量控制,进来看看吧!!!
前言 🌟🌟本期讲解关于TCP协议的重要的机制“连接的建立和断开”~~~ 🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客 🔥 你的点赞就是小编不断更新的最大动力 …...
无人机避障——使用三维PCD点云生成的2D栅格地图PGM做路径规划
着重介绍通过对三维 PCD 点云进行处理生成 2D 栅格地图 PGM,而后将该 PGM 地图充分运用到无人系统路径规划之中,使得无人机能够依据此规划合理避开飞行路线上可能出现的障碍物。(解决如何使用PGM的问题) Hybrid A*算法 参考博客…...
supermall项目上拉加载bug分析
1.bug分析 bug出现的过程是这样的:better-scroll框架会计算滚动内容的高度(通过BScroll对象的scrollerHeight属性记录滚动内容的高度) 由于内容中的图片资源还未加载成功 就已经完成计算 导致计算结果错误 而计算之后 图片资源随之加载完成 这时候better-scroll框架…...
【linux网络编程】| socket套接字 | 实现UDP协议聊天室
前言:本节内容将带友友们实现一个UDP协议的聊天室。 主要原理是客户端发送数据给服务端。 服务端将数据再转发给所有链接服务端的客户端。 所以, 我们主要就是要实现客户端以及服务端的逻辑代码。 那么, 接下来开始我们的学习吧。 ps:本节内容…...
第二届开放原子大赛-开源工业软件算法集成大赛即将启动!
第二届开放原子大赛-开源工业软件算法集成大赛作为开放原子开源基金会组织举办的开源技术领域专业赛事,聚焦开源底座框架平台建设,通过组件化集成的开发模式,丰富平台功能模块,拓展其应用场景,以此促进工业软件生态的繁…...
PXC集群(Percona XtraDB Cluster )
一、简介 基于Galera Cluster技术的开源分布式数据库解决方案,它允许你在多个MySQL服务器之间创建一个同步的多主复制集群。 特点: * 多主复制架构: PXC集群支持多主复制,每个节点都可以同时读写数据,这使得应用程序可以更灵活地进行负载均衡和高可用性设置。* 同步复制:…...
分布式光伏是什么意思?如何高效管理?
分布式光伏系统是指在用户现场或靠近用电现场配置较小的光伏发电供电系统,以满足特定用户的需求。根据通知,分布式光伏系统主要有以下几类定义: 10kV以下电压等级接入,且单个并网点总装机容量不超过6MW的分布式电源:这…...
提问GPT
1 理解GPT AI模型即采用深度学习技术的人工神经网络。 你不会被AI取代,而是会被熟练运用AI的人取代 1.1 问答或对话是普通用户与这一轮新AI产品的典型交互方式。 GPT生成式预训练转换器 了解当前GPT产品的形式: 通用聊天机器人…...
李飞飞团队新突破:低成本高泛化机器人训练法,零样本迁移成功率90%!
在机器人训练中,如何高效地利用模拟环境一直是研究者们关注的重点问题。 近日,美国斯坦福大学李飞飞教授团队提出了一种突破性的“数字表亲”(digital cousins)概念。这一创新方法既保留了数字孪生的优势,又大大降低了…...
PHP内存马:不死马
内存马概念 内存马是无文件攻击的一种常用手段,利用中间件的进程执行某些恶意代码。首先要讲的是PHP不死马,实质上就是直接用代码弄一个死循环,强占一个 PHP 进程,并不间断的写一个PHP shell,或者执行一段代码。 不死…...
【python】OpenCV—Connected Components
文章目录 1、任务描述2、代码实现3、完整代码4、结果展示5、涉及到的库函数6、参考 1、任务描述 基于 python opencv 的连通分量标记和分析函数,分割车牌中的数字、号码、分隔符 cv2.connectedComponentscv2.connectedComponentsWithStatscv2.connectedComponents…...
【优选算法篇】前缀之序,后缀之章:于数列深处邂逅算法的光与影
文章目录 C 前缀和详解:基础题解与思维分析前言第一章:前缀和基础应用1.1 一维前缀和模板题解法(前缀和)图解分析C代码实现易错点提示代码解读题目解析总结 1.2 二维前缀和模板题解法(二维前缀和)图解分析C…...
win10 更新npm 和 node
win10 更新npm 和 node win10 更新 npm winR 输入cmd,打开命令行,并输入如下 # 查看当前npm版本 npm -v # 清缓存 npm cache clean --force # 强制更新npm,试过npm update -g,没起作用,版本没变化 npm install -g …...
搜索引擎算法更新对网站优化的影响与应对策略
内容概要 随着互联网的不断发展,搜索引擎算法也在不断地进行更新和优化。了解这些算法更新的背景与意义,对于网站管理者和优化人员而言,具有重要的指导意义。不仅因为算法更新可能影响到网站的排名,还因为这些变化也可能为网站带…...
使用 Q3D 计算芯片引线的 AC 和 DC R 和 L
摘要: 模具经常用于电子行业。了解其导联的寄生特性对于设计人员来说很重要。Q3D 是计算 RLCG 的完美工具。它可用于高速板或低频电力电子设备。 在下面的视频中,我们展示了如何修改几何结构、设置模型和检查结果。 详细信息: 几何图形可以在 Q3D 中创建,也可以作为不同…...
前端_008_Vite
文章目录 Vite项目结构依赖构建插件 官网:https://vitejs.cn/vite3-cn/guide/ 一句话简介:前端的一个构建工具 Vite项目结构 index.html package.json vite.config.js public目录 src目录 #新建一个vite项目 npm create vitelatest原有项目引入vite需要…...
ssm007亚盛汽车配件销售业绩管理统(论文+源码)_kaic
本科毕业设计论文 题目:亚盛汽车配件销售业绩管理系统设计与实现 系 别: XX系(全称) 专 业: 软件工程 班 级: 软件工程15201 学生姓名: 学生学号: 指导教师&am…...
如何使用python完成时间序列的数据分析?
引言 时间序列分析是统计学和数据分析中的一个重要领域,广泛应用于经济学、金融、气象学、工程等多个领域。 时间序列数据是按时间顺序排列的一系列数据点,通常用于分析数据随时间的变化趋势。 本文将介绍时间序列分析的基本概念、常用方法以及如何使用Python进行时间序列…...
数字ic设计,Windows/Linux系统,其他相关领域,软件安装包(matlab、vivado、modelsim。。。)
目录 一、总述 二、软件列表 1、modelsim_10.6c 2、notepad 3、matlab 4、Visio-Pro-2016 5、Vivado2018 6、VMware15 7、EndNote X9.3.1 8、Quartus 9、pycharm 10、CentOS7-64bit 一、总述 过往发了很多数字ic设计领域相关的内容,反响也很好。 最近…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...
DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态
前言 在人工智能技术飞速发展的今天,深度学习与大模型技术已成为推动行业变革的核心驱动力,而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心,系统性地呈现了两部深度技术著作的精华:…...
针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...
边缘计算网关提升水产养殖尾水处理的远程运维效率
一、项目背景 随着水产养殖行业的快速发展,养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下,而且难以实现精准监控和管理。为了提升尾水处理的效果和效率,同时降低人力成本,某大型水产养殖企业决定…...
Qwen系列之Qwen3解读:最强开源模型的细节拆解
文章目录 1.1分钟快览2.模型架构2.1.Dense模型2.2.MoE模型 3.预训练阶段3.1.数据3.2.训练3.3.评估 4.后训练阶段S1: 长链思维冷启动S2: 推理强化学习S3: 思考模式融合S4: 通用强化学习 5.全家桶中的小模型训练评估评估数据集评估细节评估效果弱智评估和民间Arena 分析展望 如果…...
