UDP_SOCKET编程实现

news2024/11/15 18:27:37

文章目录

  • 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完成

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

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

相关文章

松材线虫多光谱数据集

松材线虫多光谱数据集 无人机&#xff1a;dji mavic3 mutispectral 波段&#xff1a;red green rededge nir rgb 面积&#xff1a;39.05平方公里 数据&#xff1a;rgb影像&#xff0c;四个单波段影像&#xff0c;NDVI GNDVI LCI NDRE OSAVI 5个指数图 分辨率&#xff1a;0.03&a…

【智路】智路OS 欢迎来到智路OS路侧操作系统开发手册

https://airos-edge.readthedocs.io/zh/latest/ 欢迎来到智路OS路侧操作系统开发手册 智路OS 是一套完整的软件和服务开放系统&#xff0c; 由路侧操作系统&#xff08;airos-edge&#xff09;&#xff0c;车端&#xff08;airos-vehicle&#xff09;和云端开发者平台共同构成…

【Spring Boot】SpringBoot自动装配-Import

目录 一、前言二、 定义三、使用说明3.1 创建项目3.1.1 导入依赖3.1.2 创建User类 3.2 测试导入Bean3.2.1 修改启动类 3.3 测试导入配置类3.3.1 创建UserConfig类3.3.2 修改启动类 3.4 测试导入ImportSelector3.4.1 创建UseImportSelector类3.4.2 修改启动类3.4.3 启动测试 3.5…

Python 二维码(QR码)生成器:使用python-qrcode简化条码创建

在数字时代&#xff0c;QR码已成为快速信息共享和数据传输的必备工具。无论是用于市场营销活动、活动签到&#xff0c;还是仅仅分享Wi-Fi凭证&#xff0c;QR码都提供了一种方便的方式来打包和扫描访问信息。今天&#xff0c;我们将探索python-qrcode库&#xff0c;这是一个强大…

Golang | Leetcode Golang题解之第409题最长回文串

题目&#xff1a; 题解&#xff1a; func longestPalindrome(s string) int {mp : map[byte]int{}for i : 0; i < len(s); i {mp[s[i]]}res : 0for _, v : range mp {if v&1 1 {res v - 1} else {res v}}if res<len(s) {res}return res }

【MyBatis精讲】从入门到精通的详细指南:简化Java持久层操作的艺术

文章目录 【MyBatis精讲】从入门到精通的详细指南&#xff1a;简化Java持久层操作的艺术1.mybatis快速入门1.1创建步骤1.2mapper代理开发模式 2.mybatis增删改查2.1查询所有数据2.2 id查询数据2.3插入数据2.4修改数据2.5删除数据2.6 mybatis多条件查询2.7 mybatis动态条件查询 …

HTML标签优先级

HTML&#xff08;HyperText Markup Language&#xff09;标签的位置对于页面的结构、性能以及可维护性至关重要。合理安排标签的位置不仅有助于提高网页的加载速度&#xff0c;还能使得代码更加清晰易懂。以下是一些关于HTML标签放置的基本规则和建议&#xff1a; 1. 文档类型…

web安卓逆向之必学HTML基础知识

文章目录 HTML基础知识一、HTML的介绍1. HTML定义2. HTML 的作用1. 定义网页的结构2. 实现超文本链接3. 支持多媒体内容4. 提供表单交互5. 提高网页的可访问性和 SEO 3. 小结 二、html的基本结构1. HTML 基本结构2. HTML 基本结构的详细介绍3. 教学案例4. 补充知识5. 小结 三、…

【网络通信基础与实践第三讲】传输层协议概述包括UDP协议和TCP协议

一、进程间的通信 通信的两端应当是两个主机中的应用进程&#xff0c;也就是说&#xff0c;端到端的通信是应用进程之间的通信 运输层有一个很重要的功能就是复用和分用&#xff0c;复用是指在发送方不同的应用进程都可以使用同一个运输层协议传送数据&#xff0c;分用是指接…

C++前后缀分解

相关知识点 C算法与数据结构 打开打包代码的方法兼述单元测试 这个算法很容易想到&#xff0c;学习了本文后&#xff0c;可以更快得想到。 前后缀分解 分治法的一种&#xff0c;将数组和字符串&#xff0c;拆分成前缀和后缀。字符串(数组&#xff09;的前缀是字符串的前i个元…

QT模型视图结构2

文章目录 Qt 模型视图结构——模型类(二)1.基本概念1.1.模型的基本结构1.2.模型索引1.3.行号和列号1.4.父项1.5.项的角色 Qt 模型视图结构——模型类(二) ​ 模型/视图结构是一种将数据存储和界面展示分离的编程方法。模型存储数据&#xff0c;视图组件显示模型中的数据&#…

ChatGPT提示词-中文版(awesome-chatgpt-prompts中文版)

原是Github上110.6K星的项目&#xff1a;GitHub - f/awesome-chatgpt-prompts: This repo includes ChatGPT prompt curation to use ChatGPT better. 我翻译成了中文需要自提 我用夸克网盘分享了「Chat GPT提示词.csv」&#xff0c;点击链接即可保存。打开「夸克APP」在线查看…

Windows11 WSL2的ubuntu 22.04中拉取镜像报错

问题描述 在windows11 WSL2的ubuntu 22.04中拉取镜像报错。错误为&#xff1a; Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting header…

深度学习的关键数据结构——张量解释

参考英文文章: https://deeplizard.com/learn/video/Csa5R12jYRghttps://deeplizard.com/learn/video/Csa5R12jYRg 什么是张量&#xff08;Tensor&#xff09; 神经网络中的输入、输出和变换都是用张量表示的&#xff0c;因此&#xff0c;神经网络编程大量使用张量。张量的概念…

【资料分析】特殊考点——拉动增长、贡献率、容斥问题

拉动增长和增量贡献率 第X产业增加值 是一个整体名称&#xff0c;例如张狗剩这是一个整体的名字 增量贡献率 部分增量/ 整体增量&#xff0c;已知增量贡献率80.6%,对应的部分增量可以求得&#xff08;现期2632&#xff0c;增长率10.3%&#xff0c;可用假设分配&#xff09;&a…

【Linux 20】进程控制

文章目录 &#x1f308; 一、创建线程⭐ 1. 线程创建函数⭐ 3. 给线程传参⭐ 4. 创建多线程⭐ 5. 获取线程 ID &#x1f308; 二、终止线程⭐1. 使用 return 终止线程⭐ 2. 使用 pthread_exit 函数终止线程⭐ 3. 使用 pthread_cancel 函数终止线程 &#x1f308; 三、等待线程⭐…

如何查看串口被哪个程序占用?截止目前最方便的方法

痛点&#xff1a;串口因为某种原因被占用&#xff0c;如何找到罪魁祸首&#xff1f; 做开发的小伙伴们&#xff0c;经常会遇到这样的问题&#xff1a;串口因为某种原因被占用&#xff0c;导致无法通讯&#xff0c;但是又找不到被哪个程序占用。只有重启电脑&#xff0c;才能解…

Python计算机视觉 第10章-OpenCV

Python计算机视觉 第10章-OpenCV OpenCV 是一个C 库&#xff0c;用于&#xff08;实时&#xff09;处理计算视觉问题。实时处理计算机视觉的 C 库&#xff0c;最初由英特尔公司开发&#xff0c;现由 Willow Garage 维护。OpenCV 是在 BSD 许可下发布的开源库&#xff0c;这意味…

[产品管理-20]:NPDP新产品开发 - 18 - 产品设计与开发工具 - 初始设计与规格定义

目录 前言&#xff1a; 一、什么是初始设计规格 二、初始设计与规格定义的工具 2.1 用户 - 功能性设计 1、定义与目的 2、主要内容 3、重要性 4、注意事项 2.2 用户 - 可用性设计 1、定义与目的 2、主要原则 3、实施步骤 4、重要性 2.3 生产 - 可生产性设计 1、…

Linux FTP服务问题排查

一、问题描述 最近linux虚拟机重启之后发现&#xff0c;FTP服务总是不正常&#xff0c;工具无法连接。 二、排查及处理过程 1、检查ftp服务是否正常安装&#xff1a;yes rpm -qa|grep vsftpd 2、检查ftp服务是否正常启动&#xff1a; systemctl status vsftpd 启动vsftpd sys…