UDP_SOCKET编程实现
文章目录
- socket编程接口
- 认识`struct sockaddr`类
- 编写一个server服务
- Client代码
- 查看启动结果
- 代码修正
- 1.获取内核分配给客户端的信息
- 2.修正不匹配ip不能访问的问题
- 不同机器之间的通信
- 利用xftp将udp_client传给wsl的ubuntu机器进行演示
- 现在模拟在windows下的udp_client代码:
- 对方发的命令也进行执行或者是打印
- udp tcp是支持全双工的, 所以我们可以实现一个聊天室
socket编程接口
socket常见接口API:

认识struct sockaddr类
网络套接字编程时,socket也分很多类:
1.unix socket:域间socket->用的是同一套接口, 不过用的是同一台机器上的文件路径,类似命名管道,负责本主机内部进行通信
2.网络socket:ip+port 网络通信(也可实现本地socket)(重点)
3.原始socket(应用层直接访问数据链路层,一般用于编写一些网络工具)
设计者想实现在不同应用场景使用一套接口,struct sockaddr{};是一个通用的地址类型


由于历史原因, 当初设计的时候不支持void*的通用接口
所以使用这样的方式
编写一个server服务
实现一个服务:
封装一个udpserver
构建服务基本框架:
UdpServer.hpp
#pragma once
#include "nocopy.hpp"
#include <iostream>
//父类内不存在拷贝, 所以基类也不存在拷贝
class UdpServer : public nocopy
{
public:UdpServer(){}void Init(){}void Start(){}~UdpServer(){}
private:
};
Main.cc
#include "UdpServer.hpp"#include <memory>int main(){ //使用std::make_unique函数初始化它std::unique_ptr<UdpServer> usvr = std::make_unique<UdpServer>();usvr->Init();usvr->Start();return 0;}
为了防止这个类服务被拷贝, 所以禁用一系列的拷贝函数
nocopy.hpp
#pragma once#include <iostream>class nocopy{public:nocopy() = default;nocopy(const nocopy&) = delete;const nocopy& operator=(const nocopy&) = delete;//推荐禁用上面那个//nocopy& operator=(const nocopy&) = delete;~nocopy() = default;
};
socket编写:

返回值:
创建成功返回一个文件描述符,出错返回-1


参数3:
确认是udp还是TCP
udp这里是固定写法
创建套接字
绑定网络信息

返回值: 成功为0 , 错误返回-1, 错误码被设置
参数2虽然是struct sockaddr但是我们要使用网络套接字中的struct sockaddr_in:

首先这个填充字段指的是:

in_addr类是指

而
是指

##表示拼接
将传入的参数与##后面的符号进行拼接
所以这个结构体内的宏代表的参数是sin_family
struct sockaddr_in local;
bzero(&local, sizeof(local)); // 指定的内存大小清零, 头文件是<strings.h>// 也可以使用memset
// 告诉系统绑定网络通信的信息
local.sin_family = AF_INET; // 协议家族,s表示socket的意思
// in表示inet, 使用ipconfig查看会发现inet表示IP地址,
// 这的in也表示ip地址, 与上文的创建socket的参数1不同, 这边只是绑定信息
local.sin_port = htons(_port);
local.sin_addr.s_addr = inet_addr(_ip.c_str());
//我们自己写的是一个主机序列, 要转化为网络序列htons();
//主机转网络短整型, 同样在结构体内的是类型匹配的

对于我们的网络IP, 同样, 我们想要1. 4字节IP 2. 转成网络序列

将输入的字符串IP转化为点分十进制IP,并返回

结构体填完, 只是在当前的用户地址空间, 但是还没有设置到内核, 需要调用bind函数
udp服务器接发消息, 它不面向连接:
收消息:

发消息

至此已完成, 运行查看:

怎么验证:

n:number数字
a:all 所有的
u:udp
p:process进程

Client代码
创建套接字

客户端信息输入:

发送信息

接受消息

查看启动结果
信息查看

带上-n选项

127.0.0.1: 本地环回地址, 通常用于进行网路cs(client server)的测试

cs都在一台机器, 用于测试将信息自己发给自己是否正确
带上-p选项

输出的信息

客户端的端口号和ip自动变成了

客户端的首次运行, 在没有发消息时, 看不到client的相关网络信息:
只有在client发送一条信息之后, 才会看到client的相关信息
说明, 客户端bind是在首次发送数据的时候, 进行由内核随机bind
代码修正
1.获取内核分配给客户端的信息
在server模块中, client首次发送的消息会被recvfrom函数接受, 那么这个函数的后两个参数就是表示这个客户端的信息
所以, 打印需要的信息

再次运行查看:

127.0.0.1: 本地环回地址, 通常用于进行网路cs(client server)的测试
cs都在一台机器, 用于测试将信息自己发给自己是否正确
为了封装性, 将客户端信息进行封装:


本地测试完成
但是我们的服务器ip绑定只能是127.0.0.1本机, 如果是实际的本地机器, 本地ip也可以, 云服务器的ip不行, 因为云服务器的IP是提供商虚拟出来的公网Ip, 不能直接进行bind
当然, 也不推荐给服务器绑定固定的IP, 使用随机ip更合适, 这样就能实现IP的动态绑定, 不然, 只能绑定的固定的ip机器进行服务器的访问
2.修正不匹配ip不能访问的问题

固定ip才能访问



对应的main.cc文件内以及udpserver.hpp文件的所有的server的ip都要去除, 这边就不再演示
不同机器之间的通信
利用xftp将udp_client传给wsl的ubuntu机器进行演示
传过去默认没有可执行 chmod +x udp_client即可
这边演示两台机器上的相互通信, 原机是虚拟机ubuntu机器
现在在windows下使用wsl创建一台ubuntu机器, 两台机器ip不同
都是虚拟出来的ip

现在模拟在windows下的udp_client代码:
可以看到win和linux进行了通信
只不过win的汉字编码和Linux汉字的编码方式不同, 输入过去的汉字不能正确的回显, 这边只需要修改win的终端编码方式即可,这边就不再演示
对方发的命令也进行执行或者是打印
可以使用exec*系列进行使用, 不过这边利用popen函数
做两件事:
1.创建管道
2.识别字符指令, fork创建子进程并执行

可以利用FILE的文件指针, 返回command的结果
type可以利用r w r+等方式来进行处理我们的这个FILE
最后使用pclose进行关闭
打开失败就返回nullptr



udp tcp是支持全双工的, 所以我们可以实现一个聊天室
udp+线程池实现聊天室:
在线程池中, 任务现在是一个函数方法

在server启动的时候
首先进行, 将远端的信息接收进buf中,同时被填充的peer结构体中包含对应机器的port和ip
然后判断就收消息成功之后, 添加用户和用户输入的信息获取, 然后进行message的处理方法Route与当前对象, 当前客户端的信息, 当前的message绑定为task, 然后将这个task添加到线程池中

其中:
添加用户操作为看他是否在当前的用户列表中,不在,就添加

收到的message消息的处理方式是

将给定的消息message通过套接字sock发送给所有在线用户
然后在线程池中, 进行阻塞队列式的执行访问
然后对client进行多线程修改, 一个线程专门用于收消息, 一个线程专用于发消息, 主线程用于操作这个整体流程

整体没变, 实现模块化的划分:

聊天室实现成功, 但是输出和输入会混在一起. 再次修改
在linux中, 每个 终端是在/dev/pts 目录下有存在, 直接在这边输出信息也行, 方法有很多, 这边可以使用向/dev 输出的操作, 我们使用另一种方式
在输出消息的时候, 代码部分是向cerr打印, 那么我们可以利用管道, 在终端使用重定向实现输入输出的分别实现
1.创建管道

2.重定向输出
server端不变

演示

现在在回回显处进行修改代码, 以便确认身份
主要是在message进行修改,

然后输出的时候, 直接输出就行

结果演示:

就此, udp_socket完成
相关文章:
UDP_SOCKET编程实现
文章目录 socket编程接口认识struct sockaddr类 编写一个server服务Client代码查看启动结果代码修正1.获取内核分配给客户端的信息2.修正不匹配ip不能访问的问题 不同机器之间的通信利用xftp将udp_client传给wsl的ubuntu机器进行演示现在模拟在windows下的udp_client代码: 对方…...
【网络】高级IO——阻塞IO和非阻塞IO的实现
目录 一.文件描述符的默认行为——阻塞IO 二.非阻塞IO 2.1.在打开文件或创建套接字时设置非阻塞模式: 2.2.在使用网络I/O接口时请求非阻塞行为: 2.3.fcntl函数 一.文件描述符的默认行为——阻塞IO 在Linux系统中,无论是通过open系统调用…...
ASPICE培训:打造卓越的汽车软件开发能力
随着汽车行业的快速发展和智能化技术的不断演进,汽车软件开发已成为汽车制造过程中不可或缺的一部分。为了确保汽车软件的质量、可靠性和安全性,ASPICE(Automotive SPICE)作为一种国际公认的汽车软件开发过程评估标准,…...
基于Python的人工智能应用案例系列(2):分类
在本篇文章中,我们将探讨分类问题,具体的应用场景是贷款审批预测。通过该案例,我们将学习如何使用Python处理分类问题,训练模型并预测贷款是否会被批准。 案例背景 该数据集包含贷款申请的相关信息,目标是预测贷款是否…...
演示:基于WPF自绘的中国省份、城市、区县矢量地图
一、目的:演示一个基于WPF自绘的中国省份、城市、区县矢量地图 二、效果 国 省 市 三、功能 支持实际经纬度显示 支持平移,缩放等功能 显示中国地图 显示各个省份地图 显示各个省份地图(包含在表格中,包含缩率图) 显…...
同时拥有独显和核显,怎么让应用程序选择使用哪个GPU?
看你现在使用的是核显还是独显 勾选上GPU引擎选项,后面便会标识你所使用的是哪种显卡,如果是独立显卡,就可以免去后续的操作;如果不是,那么请继续接下来的操作。 将你需要使用独显的程序换成gpu1(独显&am…...
C++八股文之面向对象篇
🤖个人主页:晚风相伴-CSDN博客 思维导图链接:面向对象的性质 持续更新中…… 💖如果觉得内容对你有帮助的话,还请给博主一键三连(点赞💜、收藏🧡、关注💚)吧 …...
点云深度学习系列:Sam2Point——基于提示的点云分割
文章:SAM2POINT:Segment Any 3D as Videos in Zero-shot and Promptable Manners 代码:https://github.com/ZiyuGuo99/SAM2Point Demo:https://huggingface.co/spaces/ZiyuG/SAM2Point 1)摘要 文章介绍了SAM2POINT,这是…...
mysql学习教程,从入门到精通,TOP 和MySQL LIMIT 子句(15)
1、TOP 和MySQL LIMIT 子句内容 在SQL中,不同的数据库系统对于限制查询结果的数量有不同的实现方式。TOP 关键字主要用于 SQL Server 和 Access 数据库中,而 LIMIT 子句则主要用于 MySQL、PostgreSQL(通过 LIMIT/OFFSET 语法)、S…...
备战软考Day02-数据结构与算法
1.基本概念与三要素 1.什么是数据 数据是信息的载体,是描述客观事物属性的数、字符及所有能输入到计算机中并被计算机程序识别和处理的符号的集合。数据是计算机程序加工的原料。 2.数据元素、数据项 数据元素是数据的基本单位,通常作为一个整体进行…...
COMP 6714-Info Retrieval and Web Search笔记week1
哭了哭了,这周唯一能听懂的就这门 目录 IR(Information Retrieval)是什么?IR的基本假设Unstructured (text) vs. structuredDocuments vs. Database Records比较文本(Comparing Text)IR的范围(Dimensions of IR)IR的任…...
C++在Linux实现多线程和多进程的TCP服务器和客户端通信
多进程版本 服务器 #include <arpa/inet.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <sys/wait.h> #include <signal.h> #include <string&…...
音视频开发常见的开源项目汇总
FFmpeg 地址:https://ffmpeg.org/介绍:FFmpeg 是一个非常强大的开源多媒体框架,它可以用来处理视频和音频文件。它支持多种格式的转换、编码、解码、转码、流处理等。FFmpeg 包括了 libavformat、libavcodec、libavutil、libswscale、libpos…...
Java操控Redis (面经之 使用Redis)
操控Redis的工具 ReactiveRedisTemplate 和 RedisTemplate : RedisTemplate: 它是一个通用的模板类,可以使用任何序列化策略来序列化和反序列化键和值。默认情况下,它使用 JdkSerializationRedisSerializer 序列化值,并使用 Strin…...
【计网】从零开始使用UDP进行socket编程 --- 服务端业务实现
在我们每个人都曾经历过“沮丧”时刻里, 如果我们不能对别人说有益的好话, 那我们最好还是什么也别说。 --- 卡耐基 《人性的弱点》--- 从零开始使用UDP进行socket编程 1 前情提要2 单词翻译2.1 业务需求2.2 设计字典类2.3 服务端与客户端逻辑2.4 运…...
正式发售!《黑神话:悟空》背后的技术力量——UE5与实时云渲染
千呼万唤始出来,《黑神话:悟空》终于在今年8月发售了,相信大家都已经玩起来了! 作为国产游戏的画质巅峰之作,《黑神话:悟空》凭借其令人叹为观止的画面质量和游戏体验,赢得了广泛的好评。这一切…...
qt-creator-10.0.2之后版本的jom.exe编译速度慢下来了
1、Qt的IDE一直在升级,qt-creator的新版本下载地址 https://download.qt.io/official_releases/qtcreator/ 2、本人一直用的是qt-creator-10.0.2版本,官网历史仓库可以下载安装包qt-creator-opensource-windows-x86_64-10.0.2.exe https://download.qt…...
2024CSP-J初赛全真模拟卷选择题篇(原创,难度偏简单)
注意,本卷由再临TSC原创,禁止转载! 本卷难度偏简单,若想要通过初赛本卷应拿80分左右 查看答案的方法: if(设备"PC") { 把光标移到答案上面,选中答案,就会显示(); } …...
【Android 13源码分析】WindowContainer窗口层级-4-Layer树
在安卓源码的设计中,将将屏幕分为了37层,不同的窗口将在不同的层级中显示。 对这一块的概念以及相关源码做了详细分析,整理出以下几篇。 【Android 13源码分析】WindowContainer窗口层级-1-初识窗口层级树 【Android 13源码分析】WindowCon…...
C# 开发教程-中级教程
1.C# 多线程/异步 C# 异步编程Task整理(一) C# 异步编程Task整理(二)异常捕捉 C# 异步编程Task(三) async、await C#中创建线程,创建带参数的线程 C# 线程同步之排它锁/Monitor监视器类 C# lock关键词/lock语句块…...
iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...
