零基础学习计算机网络编程----socket实现UDP协议
本章将会详细的介绍如何使用 socket 实现 UDP 协议的传送数据。有了前面基础知识的铺垫。对于本章的理解将会变得简单。将会从基础的 Serve 的初始化,进阶到 Client 的初始化,以及 run。最后实现一个简陋的小型的网络聊天室。
目录
1.UdpSever.h
1.1 构造函数
1.2 initServe 函数
2. UdpSever.cc
3. udpClient.hpp
3.1 构造函数
3.2 init(初始化函数)
3.3 run
4. udpClient.cc
5. 对于 UdpSever.h 中run函数的实现
6. 结尾
1.UdpSever.h
在这个文件里面需用定义 Sever 的一个类,里面变量为:_ip, _port,_sockfd。要实现的函数为构造函数、初始化(init)、运行(run)、析构函数。进行初始化是实现服务器的网络的核心,当然run 也非常重要。关于实现构造函数的时候为什么只需要 port 以及defaultip是什么我后面都会进行讲解。
class udpServer{public:udpServer(uint16_t port): _ip(defaultIp), _port(port){}void initServe(){}void start(){}~udpServer() {}private:uint16_t _port;string _ip;int _sockfd;};
1.1 构造函数
里面使用了 port,因为这个服务器的特点,我们使用的 linux 有2个,或是2个以上的 ip,因此我们在进行绑定的时候是不可以进行直接绑定的。要不然当使用不同的 ip 的时候,会导致数据无法从客户端发送到服务端。因此需要使用默认的ip = “0.0.0.0”。(后面的cc文件中使用智能指针的方式进行定义)
1.2 initServe 函数
进行初始化,本质就是使用 socket 打开文件,会返回文件描述符(可以理解为打开网卡这个文件,然后进行传递数据)。然后进行 bind ,使用 struct sockaddr_in loacl, 对于这个结构体里面的数据进行填写,然后进行 bind 绑定。
对于soket 函数,官方的定义为:返回一个文件描述符fd, 第一个参数是选择网络通信还是本地通信,第二变量表示是使用udp 还是 tcp, 我们使用的是 sock_dgram(数据报的方式发送数据),第三个变量表示阻塞状态默认为 0;最后如何是返回 -1 进行退出操作。
_sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (_sockfd == -1){cerr << "socket error" << errno << " : " << strerror(errno) << endl;exit(SOCKET_ERROR);}
使用 bind 函数进行绑定。 需要文件的描述符,一个 sockaddr 的结构体,sizeof(sockaddr 的结构体)。关键就是在于处理这个 sockaddr 我们使用的 sockaddr_in 然后进行类型的转化。最后我们使用的是先进行清零,然后 第一个位置放上协议家族:AF_INET, 第二位置放上 port 端口号需要使用 htons(host主机到net网络当中为 short 的 16 位的方式), ip 直接使用 inet_addr(将点分十进制转化位 32 位的整形,然后变成网络当中的大端方式发送)。还需要注意的是由于 inet_addr 传递的字符串的指针,所以是使用 c_str。整体的代码如下。
void initServe(){// 使用 socket 函数,然后进行绑定_sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (_sockfd == -1){cerr << "socket error" << errno << " : " << strerror(errno) << endl;exit(SOCKET_ERROR);}// 进行band 绑定,注意是使用结构体进行绑定struct sockaddr_in local;bzero(&local, sizeof(local));local.sin_family = AF_INET;local.sin_port = htons(_port);local.sin_addr.s_addr = inet_addr(_ip.c_str());// 设置好 addr_in 就去进行绑定int n = bind(_sockfd, (struct sockaddr *)&local, sizeof(local));if (n == -1){cerr << "bind_error" << " : " << strerror(errno) << endl;exit(BIND_ERROR);}}
对于启动函数,他本质就是一个无限的循环。
for(;;)
2. UdpSever.cc
就。是在运行的时候,我们需要用户使用 ./ UdpSever port 如果不是就会提示如何使用。然后因为 argv[1] 使用的是字符串的方式,直接 atoi 就可以转化位整型。然后就是智能指针的定义,进行初始化,以及启动函数。
#include "udpServe.hpp"
#include <memory>
#include <unordered_map>using namespace djx;
static void Usage(std::string tmp)
{std::cout << "Usage:\n" << tmp << "local_port\n\n";
}
int main(int argc, char* argv[])
{if(argc != 2){//说明输入错误,需要重新输入Usage(argv[0]);exit(IN_ERROR);}uint16_t port = atoi(argv[1]);//然后需要启动定义好的 udpstd::unique_ptr<udpServer> usvr(new udpServer(port));usvr->initServe();usvr->start();return 0;
}
最终实现的样式为这样,已经成功运行了。
3. udpClient.hpp
跟udpSever是一样的都是4个函数,接下来我将会一一介绍。
3.1 构造函数
这个构造函数就需要告诉你,你要发送的服务器的ip地址,以及 port 端口号。 所以定义如下:
udpClient(uint16_t serveport, string serveip):_serveport(serveport),_serveip(serveip){}
3.2 init(初始化函数)
与udpSever一样都是使用socket,然后使用bind。但是这个bind 不要们进行显示的绑定,但是是需要进行绑定的。 为了保证独立性,ip 与 port 由操作系统为我们进行提供。
void initClient(){//click 是实现服务端的传送数据_sockfd = socket(AF_INET, SOCK_DGRAM, 0);if(_sockfd == -1){cerr << "socket error" << errno << " : " << strerror(errno) << endl;exit(2);}//进行绑定不要显示的进行绑定,是操作系统会帮助我们进行生成随机独立唯一的一个 port}
3.3 run
run就是运行函数,使用函数接口 sendto ,这个是一个输出型函数。是要将buf 缓冲里面的东西发送到 severip 和 severport 的 服务器当中,所以需要使用 sockaddr_in 对于里面的内容进行初始化。然后是对于 buffer 内容的输入。是使用 string message 类型的来进行存放数据。
void run(){//需要使用函数 sendto, 但是在之前需要先获取到 secve 的ip 以及 portstruct sockaddr_in serve;serve.sin_family = AF_INET;serve.sin_port = htons(_serveport);serve.sin_addr.s_addr = inet_addr(_serveip.c_str());while(1){string message;cin >> message;sendto(_sockfd, message.c_str(), sizeof(message), 0, (struct sockaddr*)&serve, sizeof(serve));}}
4. udpClient.cc
与 Serve 类型都是先进行判断输入的argc 是为 3,如果是就进行启动。不是就告诉你如何使用。
#include "udpClient(fianll).hpp"
#include <memory>
using namespace std;
using namespace djx;
static void Usage(std::string tmp)
{cout << "Usage:\n\t" << tmp << " local_ip "<< "local_port\n\n";
}
int main(int argc, char* argv[])
{if(argc != 3){Usage(argv[0]);exit(1);}uint16_t port = atoi(argv[2]);string ip = argv[1];std::unique_ptr<udpClient> uclick(new udpClient(port, ip));uclick->initClient();uclick->run();return 0;
}
5. 对于 UdpSever.h 中run函数的实现
start 函数需要接受从客服端发来的信息,通过之前启动的 sokce 以及 bind,启动了 udp 协议。内核就会帮助我们对于定义的 struct scokaddr_in 进行内容的填充(来自客户端发送过来的数据)。里面需要的函数为 recvfrom 这是一个输入输出型参数。从 struct scokaddr_in 获取输入参数,将参数输出到 buffer 这个缓存当中,然后进行打印。
整体的实现如下,其中 full 定义为 1024 个整形。然后 s 表示的是buffer 里面读取到的个数,如果是小于0,就表示没有数据,直接结束此次循环。为了照顾计算机网络的数据严格传送的特点,len 的长度需要定义为 socklen_t 。使用 char 的时候写入的大小是从 0 开始的,所以是要sizeof - 1.
void start(){char buffer[full]; for (;;){// 用来存放 哪个click发送来的数据struct sockaddr_in peer;socklen_t len = sizeof(peer); // 为了照顾vecvfrom函数,所以使用这个socken_t;ssize_t s = recvfrom(_sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&peer, &len);if (s > 0){buffer[s] = 0; string message = buffer; // s表示获取到的长度string click_ip = inet_ntoa(peer.sin_addr); // 直接就是从结构体变过来int click_port = ntohs(peer.sin_port);cout << click_ip << "[" << click_port << "]#" << message << endl;}}}
6. 结尾
到此 udp 简单实现已经结束了,还不是很全面因为我们是要得到数据,然后实现相应的工作,这里还没有实现功能,就是实现了一个简陋的网络聊天室。任意一台主机通过输入./udpClient ip + port, 我都可以在我的服务器上看见对应的信息。
udp网络聊天室(最低级),也是一个 demo
以上是对于计算网络中基础知识的了解,这个文章用于我的学习记录,如果是有其他的错误还请批评指正。如果对你有帮助还请给我点个赞👍👍👍。
相关文章:

零基础学习计算机网络编程----socket实现UDP协议
本章将会详细的介绍如何使用 socket 实现 UDP 协议的传送数据。有了前面基础知识的铺垫。对于本章的理解将会变得简单。将会从基础的 Serve 的初始化,进阶到 Client 的初始化,以及 run。最后实现一个简陋的小型的网络聊天室。 目录 1.UdpSever.h 1.1 构造…...

谷歌地图2022高清卫星地图手机版v10.38.2 安卓版 - 前端工具导航
谷歌地图2022高清卫星地图手机版是由谷歌公司推出的一款非常好用的手机地图服务软件,用户能够通过精准的导航和定位来查看地图,周边的商店等生活服务都会在地图上显示,用起来超级方便。 谷歌卫星高清地图 下载链接:夸克网盘分享 …...

RAG的ETL Pipeline源码解读
原文链接:SpringAI(GA):RAG下的ETL源码解读 教程说明 说明:本教程将采用2025年5月20日正式的GA版,给出如下内容 核心功能模块的快速上手教程核心功能模块的源码级解读Spring ai alibaba增强的快速上手教程 源码级解读 版本&a…...

杭州白塔岭画室怎么样?和燕壹画室哪个好?
杭州作为全国美术艺考集训的核心区域,汇聚了众多实力强劲的画室,其中白塔岭画室和燕壹画室备受美术生关注。对于怀揣艺术梦想的考生而言,选择一所契合自身需求的画室,对未来的艺术之路影响深远。接下来,我们将从多个维…...
Linux文件系统:从VFS到Ext4的奇幻之旅
Linux文件系统:从VFS到Ext4的奇幻之旅 从虚拟文件到物理磁盘的魔法桥梁 引言:数据宇宙的"时空管理者" 当你在Linux终端输入ls -l时,一场跨越多个抽象层的精密协作悄然展开。文件系统作为操作系统中最复杂且最精妙的子系统之一&…...
5月底 端午节
感觉五月写的很少啊,尤其是这一周,真的事情特别多可能。但是实际上我晚上回宿舍之后大概九点十点这块,最后睡觉一般在十一点半到十二点。这一段时间我基本上都是浪费了。要么在打游戏要么在刷视频。但是最基本的生活保障和学习都没有做好。。…...
为何选择Spring框架学习设计模式与编码技巧?
📌 结论先行 推荐项目:Spring Framework 推荐理由:设计模式覆盖全面 编码技巧教科书级实现 Java 生态基石地位 🏆 三维度对比分析 维度SpringMyBatisXXL-JOB设计模式⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐代码抽象⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐生态价…...
软件评测师 综合测试 真题笔记
计算机组成原理 用作科学计算为主的计算机,其对主机的运算速度要求很高,应该重点考虑 CPU的主频和字长,以及内存容量; 用作大型数据库处理为主的计算机,其对主机的内存容量、存取速度和外存储器的读写速度要求较高; 对…...

晶台光耦在手机PD快充上的应用
光耦(光电隔离器)作为关键电子元件,在手机PD快充中扮演信号隔离与传输的“安全卫士”。其通过光信号实现电气隔离,保护手机电路免受高电压损害,同时支持实时信号反馈,优化充电效率。 晶台品牌推出KL817、KL…...
JS对数据类型的检测
typeof对基本数据类型有用,但是对引用数据类型不行 console.log(typeof 2)//number console.log(typeof [])//object 失效 instanceof只对引用数据类型有用 console.log([] instanceof Array) //true console.log(2 instanceof String) //false constructor基本…...
llama.cpp:纯 C/C++ 实现的大语言模型推理引擎详解一
🚀 llama.cpp:纯 C/C 实现的大语言模型推理引擎详解 一、什么是 llama.cpp? llama.cpp 是一个由 Georgi Gerganov 开源的项目,旨在使用纯 C/C 在 CPU 上运行 Meta 的 LLaMA 系列大语言模型。 它通过量化、优化注意力机制和内存…...

【亲测有效 | Cursor Pro每月500次快速请求扩5倍】(Windows版)Cursor中集成interactive-feedback-mcp
前言:使用这个interactive-feedback-mcp组件可以根据用户反馈来决定是否结束这一次的请求。如果本次请求并没有解决我们的问题,那我们便可以选择继续这次请求流程,直到问题解决。这样的话,就可以避免为了修复bug而白白多出的请求。…...
BaseTypeHandler用法-笔记
1.BaseTypeHandler简介 org.apache.ibatis.type.BaseTypeHandler 是 MyBatis 提供的一个抽象类,通过继承该类并实现关键方法,可用于实现 Java 类型 与 JDBC 类型 之间的双向转换。当数据库字段类型与 Java 对象属性类型不一致时(如ÿ…...
鸿蒙OSUniApp集成WebGL:打造跨平台3D视觉盛宴#三方框架 #Uniapp
UniApp集成WebGL:打造跨平台3D视觉盛宴 在移动应用开发日新月异的今天,3D视觉效果已经成为提升用户体验的重要手段。本文将深入探讨如何在UniApp中集成WebGL技术,实现炫酷的3D特效,并特别关注鸿蒙系统(HarmonyOS)的适配与优化。 …...
华为盘古 Ultra MoE 模型:国产 AI 的技术突破与行业影响
2025 年 5 月 30日,华为正式发布参数规模达 7180 亿的盘古 Ultra MoE 模型,全程基于昇腾 AI 计算平台完成训练。这一进展标志着中国在超大规模人工智能模型领域的自主研发能力达到新高度,同时也为全球 AI 技术发展提供了新的技术路径。 盘古 …...
Payload CMS:开发者优先的Next.js原生开源解决方案,重新定义无头内容管理
在无头内容管理系统(CMS)竞争激烈的今天,Payload CMS凭借其独特的开发理念和技术架构迅速崛起,成为Microsoft、ASICS、Blue Origin等创新企业的选择。这款基于Node.js与TypeScript构建的开源解决方案,正在彻底改变开发…...

CRM管理软件的数据可视化功能使用技巧:让数据驱动决策
在当今数据驱动的商业环境中,CRM管理系统的数据可视化功能已成为企业优化客户管理、提升销售效率的核心工具。据企销客研究显示,具备优秀可视化能力的CRM系统,用户决策效率可提升47%。本文将深入解析如何通过数据可视化功能最大化CRM管理软件…...

linux批量创建文件
文章目录 批量创建空文件touch命令批量创建空文件循环结构创建 创建含内容文件echo重定向多行内容写入 按日期创建日志文件根据文件中的列内容,创建文件一行只有一列内容一行有多列内容 批量创建空文件 touch命令批量创建空文件 # 创建文件file1.txt到file10.txt …...

颠覆传统!单样本熵最小化如何重塑大语言模型训练范式?
颠覆传统!单样本熵最小化如何重塑大语言模型训练范式? 大语言模型(LLM)的训练往往依赖大量标注数据与复杂奖励设计,但最新研究发现,仅用1条无标注数据和10步优化的熵最小化(EM)方法…...
华为数据之道 精读——【173页】读书笔记【附全文阅读】
在数字化浪潮中,企业数据管理的优劣直接关乎竞争力。华为凭借丰富实践经验总结的《华为数据之道》,为企业提供了全面且深入的数据治理方案。 笔记聚焦数字化转型与数据治理的紧密联系。华为作为非数字原生企业,在转型过程中克服了产业链条长、数据复杂等诸多难题,其…...
数据库OCP专业认证培训
认证简介 OCP 即 Oracle 数据库认证专家(Oracle Certified Professional),是 Oracle 公司的 Oracle 数据库 DBA(Database Administrator 数据库管理员)认证课程。通过该认证,表明持证人能够管理大型数据库…...

ssm学习笔记day04
RequestMapping 首先添加依赖 Maven的配置 测试 在controller创建HelloController,如果只加RequestMapping,默认跳转到新页面 如果要是加上ResponseBody就把数据封装在包(JSON),标签RestController是前后分离的注解(因为默认用…...

Read View在MVCC里如何工作
Read View的结构 Read View中有四个重要的字段: m_ids:创建 Read View 时,数据库中启动但未提交的「活跃事务」的事务 id 列表 。min_trx_id:创建 Read View 时,「活跃事务」中事务 id 最小的值,即 m_ids …...
HDFS 写入和读取流程
HDFS 写入流程细化 1. 主线流程速记口诀 “先找主脑定文件,分配块副找节点;流水传块多副本,写完通知主脑存。” 2. 详细流程拆解 1. 客户端请求上传(Create 文件) 关键方法: org.apache.hadoop.fs.File…...

建筑工程施工进度智能编排系统 (SCS-BIM)
建筑工程施工进度智能编排 (SCS-BIM) 源码可见于:https://github.com/Asionm/SCS-BIM 项目简介 本项目是一个面向建筑工程的施工进度智能编制平台,用户只需上传一份标准 IFC 建筑信息模型文件,系统将自动完成以下任务: 解析模…...
Laravel模型状态:深入理解Eloquent的隐秘力量
Laravel的Eloquent ORM(对象关系映射)提供了强大且灵活的功能来处理数据库操作。深入理解Eloquent模型状态对于优化应用程序性能和维护代码的简洁性至关重要。本文将详细探讨Laravel Eloquent的模型状态及其隐秘力量。 一、Eloquent模型的基本概念 Elo…...
Spring Cloud Eureka:微服务架构中的服务注册与发现核心组件
前言 在微服务架构日益流行的今天,服务注册与发现机制成为了构建弹性、可扩展分布式系统的关键。作为Spring Cloud生态中的核心组件,Eureka为微服务架构提供了高效的服务注册与发现解决方案。本文将深入探讨Eureka的设计原理、核心机制以及在实际项目中…...
matlab实现求解兰伯特问题
求解兰伯特问题的matlab代码,非常好用 solve_lambertLYP.m , 1899 StumpffC.m , 136 StumpffdF.m , 294 StumpffF.m , 151 StumpffS.m , 167 Stumpffy.m , 96 text2.m , 104...
iOS 集成网易云信的音视频呼叫组件
云信官方文档在这 前提是集成了云信IM,并且已经IM登录成功,如果没有集成IM的看这里:iOS 集成网易云信IM-CSDN博客 1、CocoPods集成 #云信 pod NIMSDK_LITE, 10.8.0pod NERtcSDK, 5.6.50#rtc基础SDK pod NEChatUIKit#呼叫组件API组件 pod NE…...
【Elasticsearch】search_after不支持随机到哪一页,只能用于上一页或下一页的场景
search_after 确实不支持随机访问(即直接跳到任意一页),因此在前端需要随机跳转到某一页的场景中,使用 search_after 是不合适的。这种情况下,更适合使用 from 和 size 来实现分页。 为什么 search_after 不支持随机访…...