Linux网络编程——UdpServer - 实践

news/2025/10/21 17:38:07/文章来源:https://www.cnblogs.com/yxysuanfa/p/19156014

 服务端基本框架

#include 
#include "LOG.hpp"
static const int defaultsockfd = -1;
class UdpServer
{
public:UdpServer(uint16_t port)//构造:_sockfd(defaultsockfd),_port(port),_isrunning(false){}//服务初始化void InitServer(){}//开始运行void Start(){}~UdpServer()//析构{}
private:int _sockfd;uint16_t _port;bool _isrunning;//判断服务端是否运行
};

为什么没有ip呢?到时候IP整合在InitAddr.hpp中

 UdpServer.hpp

#include 
#include 
#include 
#include 
#include 
#include
#include "LOG.hpp"
enum
{SOCKET_ERROR=1,BIND_ERROR,USAGE_ERROR
};
const static int defaultsockfd = -1;
class UdpServer
{
public:UdpServer(uint16_t port)//构造:_sockfd(defaultsockfd),_port(port),_isrunning(false){}//服务初始化void InitServer(){//创建套接字_sockfd = socket(AF_INET,SOCK_DGRAM,0);if(_sockfd<0)//创建失败,日志报错,退出{LOG(FATAL,"socket error:%s,%d\n",strerror(errno),errno);exit(SOCKET_ERROR);}//创建成功LOG(INFO,"socket create success,sockfd:%d\n",_sockfd);//填充sockaddr_in结构struct sockaddr_in local;memset(&local,0,sizeof(local));//清一下结构里面的数据local.sin_family=AF_INET;//网络通信//port需要经过网络传输给对面的client,主机序列要先转网络序列local.sin_port=htons(_port);local.sin_addr.s_addr=INADDR_ANY;//bindint n = bind(_sockfd,(struct sockaddr*)&local,sizeof(local));if(n<0)//绑定失败{LOG(FATAL,"bind error,%s:%d\n",strerror(errno),errno);exit(BIND_ERROR);}//绑定成功LOG(INFO, "socket bind success\n");}//开始运行void Start(){_isrunning = true;while(_isrunning)//服务一般都是一直运行的死循环{LOG(DEBUG,"sever is running...\n");sleep(1);}}~UdpServer()//析构{}
private:int _sockfd;uint16_t _port;bool _isrunning;//判断服务端是否运行
};

填充sockaddr_in记得引头文件<apra/inet.h> ;struct sockaddr_in是系统提供的数据类型

端口号port主机序列转成网络序列用htons()

在网络编程中,当一个进程需要绑定一个网络端口以进行通信时,可以使用 INADDR_ANY 作为 IP 地址参数。这样做意味着该端口可以接受来自任何 IP 地址的连 接请求,无论是本地主机还是远程主机。

那么local还只是对象,还在栈上开辟空间,所以InitServer初始化函数只有创建套接字socket以及填充sockaddr_in是不够的,需要进行绑定bind ,bind完成后server的初始化才算完成。

下面就可以写启动server的函数了;现在的软件若不是用户主动退出,就会一直运行,服务器也一样会一直运行,直到管理者不想运行了。所以Server都是死循环,那么就需要一个对象来判断服务器是否一直再跑(_isrunning)

 Server.cc

#include
#include"UdpServer.hpp"
#include 
void Usage(std::string a)
{std::cout<<"Usage:\n\t"< udps = std::make_unique(port);//初始化udps->InitServer();//启动udps->Start();return 0;
}

测试一下啊 

没有问题

下面我们来完成一些Udp服务的启动

1.我们需要让Server端先收数据

2.我们要让Server将收到的数据再发回去 

接收可以用recvfrom

recvfrom() 函数是一个系统调用,用于从套接字接收数据。该函数通常与无连接的数据报服务(如 UDP)一起使用,但也可以与其他类型的套接字使用。

man recvfrom 

参数

sockfd:一个已打开的套接字的描述符。

buf:一个指针,指向用于存放接收到的数据的缓冲区(输出型参数对应的缓冲区)。

len:缓冲区的大小/期望长度(以字节为单位)。

flags:读取方式。通常可以设置为0,但以下是一些可用的标志:

        MSG_WAITALL:尝试接收全部请求的数据。函数可能会阻塞,直到收到所有数据。
        MSG_PEEK:查看即将接收的数据,但不从套接字缓冲区中删除它【1】。
        其他一些标志还可以影响函数的行为,但在大多数常规应用中很少使用。

有人给你发消息你想不想知道他是谁?为什么?

当然想,我还要给他回消息呢。

那么通过什么信息知道对方是谁呢?socket:IP和Port(通过以下参数就可以知道是谁发的)
src_addr:一个指针,指向一个 sockaddr 结构,用于保存发送数据的源地址。

addrlen:一个值-结果参数。开始时,它应该设置为 src_addr 缓冲区的大小。当 recvfrom() 返回时,该值会被修改为实际地址的长度(以字节为单位)。

返回值 ssize_t

在成功的情况下,recvfrom() 返回接收到的字节数。
如果没有数据可读或套接字已经关闭,那么返回值为0。
出错时,返回 -1,并设置全局变量 errno 以指示错误类型。

服务端接收完如何发送呢?

可以用sendto

sendto() 函数是一个系统调用,用于发送数据到一个指定的地址。它经常与无连接的数据报协议,如UDP,一起使用。不像 send() 函数只能发送数据到一个预先建立连接的远端,sendto() 允许在每次发送操作时指定目的地址

man sendto

sendto 和recvfrom用法差不多

以下参数:

sockfd:一个已打开的套接字的描述符。

buf:一个指针,指向要发送的数据的缓冲区。

len:要发送的数据的大小(以字节为单位)。

flags:控制发送行为的标志。通常可以设置为0。

下面两个参数决定发给谁
dest_addr:指向 sockaddr 结构的指针,该结构包含目标地址和端口信息。

addrlen:dest_addr 缓冲区的大小(以字节为单位)。

返回值:

成功时,sendto() 返回实际发送的字节数。
出错时,返回 -1 并设置全局变量 errno 以指示错误类型。

服务端启动方法实现

void Start(){//之前提到的判断服务是否还在运行的变量_isrunning = true;while(_isrunning)//服务一般都是一直运行的死循环{//接收char buffer[1024];struct sockaddr_in peer;//对client端构建sockaddrsocklen_t len = sizeof(peer);//必须初始化为sizeof(peer)/peer长度ssize_t n = recvfrom(_sockfd,buffer,sizeof(buffer)-1,0,(struct sockaddr*)&peer,&len);if(n > 0)//收到了{buffer[n]=0;//在接收数据的末尾手动添加空字符\0LOG(DEBUG,"服务端获取信息:%s\n",buffer);//你收到了才能发嘛sendto(_sockfd,buffer,strlen(buffer),0,(struct sockaddr*)&peer,len);}}_isrunning = false;}

 客户端和服务端的步骤差不多,只是客户端不显示绑定

client.cc

#include
#include
#include 
#include 
#include 
#include 
#include 
void Usage(std::string a)
{std::cout<<"Usage:\n\t"< 0){buffer[n]=0;std::cout<<"服务端返回#"<

client 要不要进行 bind? 一定要 bind

但是,不需要显示 bind,client 会在首次发送数据的时候会自动进行 bind

为什么?因为server 端的端口号,一定是不可改变的,client 需 要 port,bind 随机端口.

为什么?因为客户端 会非常多. 防止大量客户端bind端口后对大量端口进行占用

client 需要 bind,但是不需要显示 bind,让本地 OS 自动随机 bind, 选择随机端口号

测试代码 

封装一下addr,方便获取Client端的ip和端口

#include 
#include 
#include 
#include 
#include 
class InetAddr
{
private:GetAddr(std::string *ip,uint16_t *port){*port=ntohs(_addr.sin_port);//网络转主机//将32位网络字节序的IPv4地址转换为点分十进制字符串*ip = inet_ntoa(_addr.sin_addr);}
public:InetAddr(struct sockaddr_in addr)//构造:_addr(addr){}std::string Ip(){return _ip;}uint16_t Port(){return _port;}~InetAddr(){}
private:struct sockaddr_in _addr;uint16_t _port;std::string _ip;
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/942505.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一键解锁!Air8000 Wi-Fi助物联网设备秒变文件服务器

物联网设备还能这样玩!Air8000 Wi-Fi模块的巧妙应用,让设备瞬间转型为功能强大的文件服务器,操作简单到只需一键解锁。接下来,我们将详细演示这一过程,让你轻松掌握物联网设备的全新用途。 本文将分享基于Air8000…

C语言中unsigned

signed(有符号)表示变量可以存储正数、负数和零 使用最高位作为符号位(0表示正,1表示负) 默认情况下,int, char, short, long 都是有符号的 unsigned(无符号)表示变量只能存储非负数(0和正数) 所有位都用于表…

解码Linux文件IO之触摸屏原理及应用

触摸屏基本概念 核心定义与作用 触摸屏是一种人机交互输入设备,通过检测手指(或触控笔)的按压、滑动等动作,将物理位置转换为数字坐标,实现 “点击屏幕操作界面” 的功能。常见应用场景:智能设备(手机、平板)、…

2025年最新游戏机和游艺机的屏幕驱动方案(含音乐播放和功放芯片)

当扫码支付普及率在一线城市突破85%,当消费者已习惯"无现金"生活,游艺机行业也走向数字化转型。深耕语音芯片领域二十六年的唯创知音电子有限公司,正是看准了这一机遇。推出了WT2606B TFT显示驱动方案。1…

2025 年最新推荐!国内加工厂家排行榜:含车铣复合 / 精密零件 / CNC 车床等领域优质企业

引言 当前国内加工行业发展迅猛,细分领域不断拓展,从车铣复合数控车床加工到尼龙塑胶精密零件制造,从非标丝杆生产到高精度走心机加工,市场需求持续攀升。但与此同时,行业内品牌数量激增,既有深耕多年的资深企业…

2025年精密球轴承厂家权威推荐榜:半导体设备/加工中心/机床主轴/直联主轴/电主轴/定制/国产高端/不锈钢/陶瓷/耐腐蚀/超高真空/真空泵/晶圆搬运机械手臂/进口替代/国产半导体/低温泵轴承精选

2025年精密球轴承厂家权威推荐榜:半导体设备/加工中心/机床主轴/直联主轴/电主轴/定制/国产高端/不锈钢/陶瓷/耐腐蚀/超高真空/真空泵/晶圆搬运机械手臂/进口替代/国产半导体/低温泵轴承精选 行业背景与发展趋势 精密…

【安徽财经大学主办】第七届管理科学信息化与经济创新发展国际学术会议 (MSIEID 2025)

第七届管理科学信息化与经济创新发展国际学术会议 2025 7th Management Science Informatization and Economic Innovation Development Conference (MSIEID 2025) 高届数 年度重磅会议 安徽财经大学主办、上海电力大学…

2025 盐城美术培训机构最新推荐榜单:涵盖全龄段课程 + 4A 信用单位,优质机构助你精准选课

引言 随着盐城美术培训需求持续增长,市场上机构数量激增但质量良莠不齐,给学员及家长选课带来极大困扰。部分机构缺乏专业师资,教学效果难以保障;有的课程体系单一,无法满足高考、中考、成人兴趣等不同场景需求;…

2025年冷水机组厂家权威推荐榜:水冷螺杆/风冷螺杆/水冷式/风冷式/螺杆式冷水机专业选购指南

2025年冷水机组厂家权威推荐榜:水冷螺杆/风冷螺杆/水冷式/风冷式/螺杆式冷水机专业选购指南 在工业制冷领域,冷水机组作为关键温控设备,其性能表现直接影响生产效率和能源消耗。随着2025年节能减排政策的深入推进,…

再看 AI 网关:助力 AI 应用创新的关键基础设施

本文将从 AI 网关的诞生、AI 网关的产品能力、AI 网关的开放生态,以及新推出的 Serverless 版,对其进行一个全面的介绍,期望对正在进行 AI 应用落地的朋友,在 AI 基础设施选型方面提供一些参考。作者:子丑 AI 网关…

2025 年独立游戏公司开发 AI 美术平台最新推荐榜单:覆盖全流程创作需求,助力团队突破美术瓶颈

引言 当前独立游戏行业蓬勃发展,但美术资源设计与生产的短板却愈发凸显,成为制约团队发展的关键因素。多数独立团队面临资金有限、专业美术人员匮乏的困境,难以完成从概念设计到最终资产的全流程创作,且传统美术流…

通过HTML演示JVM的垃圾回收-新生代与老年代 - 详解

通过HTML演示JVM的垃圾回收-新生代与老年代 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas"…

先收藏系列 工业相机的六问六答!

​ 工业相机是机器视觉系统的核心组成部分,通过光电转换原理将光信号转为电信号,关键技术特性包含高分辨率、高帧率、全局快门等,为计算机提供高质量、高可靠性的图像数据,以便进行自动化的检测、测量、识别和引导…

凌晨 2 点的朋友圈,她靠微擎实现了 “带娃赚钱两不误”

“以前总觉得做电商要懂代码、要囤货,直到遇见微擎,才发现普通人也能轻松当老板。” 家住济南的宝妈李姐,在朋友圈晒出当月营收截图时,底下满是熟人的惊叹。 去年刚休完产假的她,想找份能兼顾孩子的工作,尝试过几…

git pull中有 merge功能解释

git commit、git push、git pull、 git fetch、git merge 的含义与区别git commit:是将本地修改过的文件提交到本地库中; git push:是将本地库中的最新信息发送给远程库; git pull:是从远程获取最新版本到本地,并…

2025年信息流代运营服务商权威推荐榜:专业投放策略与高转化效果深度解析,助力品牌精准营销

2025年信息流代运营服务商权威推荐榜:专业投放策略与高转化效果深度解析,助力品牌精准营销 信息流代运营行业发展趋势与价值分析 随着数字营销进入精细化运营时代,信息流广告已成为企业获取流量、实现转化的重要渠道…

用AI帮忙,开发刷题小程序:微信小程序在线答题框架架构解析

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025 国内西服定制品牌精选榜:婚礼/高级/高端/高档/男士/女士/轻奢西装定制厂家,从智能智造到匠心传承的多元之选

在消费升级与技术迭代的双重浪潮下,西服定制这一承载着传统工艺的行业正焕发新的生机。从面料的精挑细选到版型的个性化打造,从手工缝制的温度到智能生产的效率,西服定制已从单纯的服饰制作升级为融合工艺、科技与服…

2025年工厂维保服务厂家权威推荐榜:机电维修、应急维修、设备安装维修、运维服务全方位解决方案精选

2025年工厂维保服务厂家权威推荐榜:机电维修、应急维修、设备安装维修、运维服务全方位解决方案精选 随着制造业数字化转型的深入推进,工厂维保服务已经从传统的被动维修向主动预防、智能运维转变。在工业4.0和智能制…

腾讯TCCL和阿里ACCL对比

腾讯的 TCCL(Tencent Collective Communication Library)和阿里云的 ACCL(Alibaba Collective Communication Library)都是各自云厂商为应对大规模 AI 模型训练场景,基于或参考 NVIDIA NCCL 构建的高性能集合通信…