【网络】1.UDP通信

embedded/2024/10/30 22:35:48/

UDP通信

  • 1 server
    • 1.1 server建立的步骤
    • 1.2 运行server
  • 2 client
    • 2.1 client的建立步骤
    • 2.2 运行client
  • 3 总结
    • 3.1 server
    • 3.2 client

1 server

server的启动方式是:./udpserver 8080 --> 格式就是./proc port端口

port端口自己指定

1.1 server建立的步骤

在这里插入图片描述

  1. 获取文件描述符
_sockfd = socket(AF_INET, SOCK_DGRAM, 0);  //AF_INET:表示ipv4. SOCK_DGRAM:表示UDP

socket函数就是创建套接字,返回值_sockfd就是文件描述符。
2. 获取套接字,并填充

1.套接字的内容有哪些?

套接字是一个结构体,sockaddr是套接字。
套接字分为三种:网络套接字,域间套接字和原始套接字。

可以将网络套接字/域间套接字/原始套接字看作是套接字的子类
sockaddr_in/sockaddr_un继承自sockaddr

1. 填充套接字

主要就填充三个部分:
在这里插入图片描述

sin_family:直接填充为AF_INET就行了。

local.sin_family = AF_INET;

sin_port:直接填充我们服务器启动的端口号。

local.sin_port = _port;

sin_addr:填充为我们服务器启动的ip地址。

但是这里有一个需要注意的地方:

2.sin_addr是struct in_addr类型,ip地址是string类型,该如何进行赋值呢?

在这里插入图片描述

所以,一路往下调用,最终就是uint32_t类型。

这里的uint32_t类型是网络中的ip地址类型,我们日常使用中为了方便,采用的是点分十进制(也就是string类型)。因此,需要将string转换为uint32_t类型。

这样的转化,可以使用inet_addr()函数。

local.sin_addr.s_addr = inet_addr(_ip.c_str());
  1. 将套接字和ip地址和port端口进行绑定

3.为什么要进行绑定,之前不是已经将ip地址和port填充给套接字了吗?

在绑定之前,sockaddr_in是在栈区上的,操作系统根本不知道设的值是什么,只有使用bind之后,才真正将IP地址和端口号绑定到了操作系统中。

bind()函数接口

 int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • sockfd : 之前socket()函数返回的文件描述符
  • addr:套接字。我们的套接字是sockaddr_in类型(网络套接字),因此需要强转
  • addrlen:套接字的长度,sizeof(addr)
  • 返回值:创建成功返回0,创建失败返回-1

1.2 运行server

本文想实现的功能是:客户端发送信息,服务端接收。

服务端要通过文件描述符得到客户端发来的内容,因此需要recvform()函数:

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
  • sockfd : 创建套接字时返回的文件描述符fd。
  • buf : 用来存储从网络中读取下来的数据的。
  • len : buf缓冲区的大小。
  • flags : 读取的方式,一般设置为0,即阻塞读取数据。
  • sockaddr* src_addr : 输出型参数,同样传参sockaddr_in结构体,系统会自动对这个结构体进行填充,可以获取数据的来源,包括发送方的地址类型,端口号port以及IP地址。
  • addrlen是第五个输出型结构体变量的大小所在的地址,注意类型是socklen_t*的,和bind的时候不一样。
  • 返回值ssize_t,返回读取到的数据个数,单位是字节,如果读取失败则返回-1。

里面传的参数是指针类型的参数,都可以获得他们的值。

struct sockaddr_in client;  //记录客户端(发送方)的ip地址和端口号socklen_t len = sizeof(client);//通过recvfrom拿到client结构体的ip地址,port端口等,因为sockaddr* src_addr是输出型参数int n = recvfrom(_sockfd, inbuffer, sizeof(inbuffer) - 1, 0, (sockaddr*)&client, &len);

2 client

流程:
client需要向server发送信息,因此,需要知道server的ip地址和port。在启动的时候已经知道了。只需要将ip地址和port填充到server的套接字中就行了。最后通过sendto()函数将要写入的内容通过文件描述符写到套接字中。

2.1 client的建立步骤

client的启动方式是:./udpclient 127.0.0.0.1 8080 --> 格式就是./proc ip地址 port端口

  1. 填充server的套接字
string serverip = argv[1];
uint16_t serverport = stoi(argv[2]);struct sockaddr_in server;
bzero(&server, sizeof(server));//填充套接字结构体
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(serverip.c_str());
server.sin_port = htons(serverport);
  1. 通过socket()获取文件描述符
    过程和建立server相同。
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);

4.client需要绑定吗?

客户端在发送数据时不一定需要显式绑定,因为系统会自动分配一个可用端口。客户端只需要指定目标服务器的地址和端口即可,操作系统会自动完成本地端口的分配。因此,对于客户端,bind 是可选的。

2.2 运行client

使用sendto()函数,将message的内容通过文件描述符写到server的套接字中。

string message;
char buffer[1024];while(true)
{cout << "please enter@ ";getline(cin, message);sendto(sockfd, message.c_str(), message.size(), 0, (const struct sockaddr*)&server, sizeof(server));
}

3 总结

3.1 server

  1. 根据 ./proc port的输入,得到服务器的端口
  2. 使用socket()函数获得文件描述符
  3. 填充server的套接字,包括sin_family/sin_addr/sin_port
  4. 使用bind()函数将得到的套接字和文件描述符/ip地址/port端口进行绑定
  5. 使用recvfrom()函数,通过文件描述符获得client发来的消息。可以根据recvfrom()的输出型参数获得client的套接字,从而获得client的ip地址和port端口。

3.2 client

  1. 根据 ./proc ip port的输入,得到服务器的ip地址和端口
  2. 使用socket()函数获得文件描述符
  3. 根据获得的server服务器的ip地址和端口填充server的套接字,包括sin_family/sin_addr/sin_port
  4. 使用sendto()函数将要发送的内容通过文件描述符发送server端。

代码链接:UDP通信
在这里插入图片描述


http://www.ppmy.cn/embedded/133724.html

相关文章

Redis慢查询分析优化

文章目录 一、定义二、慢查询参数配置三、慢查询日志四、排查步骤五、Redis变慢原因 一、定义 在Redis执行时耗时超过某个阈值的命令&#xff0c;称为慢查询。 慢查询日志帮助开发和运维人员定位系统存在的慢操作。慢查询日志就是系统在命令执行前后计算每条命令的执行时间&…

【GO实战课】第七讲:电子商务网站(7):性能优化和测试

1. 简介 本课程将探讨电子商务网站的性能优化和测试,以及使用GO语言实现。在本课程中,我们将介绍如何设计一个高性能、可扩展和可靠的电子商务网站,并演示如何使用GO语言编写相关代码。 本课程的目标是帮助学生理解电子商务网站的性能优化和测试原则,并提供一个实际的项目…

解决ElasticSearch启动成功却无法在浏览器访问问题

目录 前言&#xff1a; 问题复现 &#xff1a; 解决问题&#xff1a; 1、修改sysctl.conf文件 2、在sysctl.conf文件增加这段东西 3、 然后保存退出&#xff0c;输入以下命令使其生效 结语&#xff1a; 前言&#xff1a; 这篇文章是小白我今天突然启动es&#xff0c;发现e…

【视频混剪Demo】FFmpeg的使用【Windows】

#1024程序员节 | 征文# 目录 一、简介 二、音频素材页 2.1 功能描述 &#x1f449; 搜索 &#x1f449; 添加 &#x1f449; 删除 2.2 效果展示 2.3 代码实现 &#x1f449; 前端 &#x1f449; 后端 三、视频素材页 3.1 功能描述 &#x1f449; 搜索 &#x1…

力扣hot100-->递归/回溯

目录 递归/回溯 1. 17. 电话号码的字母组合 2. 22. 括号生成 3. 39. 组合总和 4. 46. 全排列 5. 78. 子集 递归/回溯 1. 17. 电话号码的字母组合 中等 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到…

macOS 15 Sequoia dmg格式转用于虚拟机的iso格式教程

想要把dmg格式转成iso格式&#xff0c;然后能在虚拟机上用&#xff0c;最起码新版的macOS镜像是不能用UltraISO&#xff0c;dmg2iso这种软件了&#xff0c;你直接转放到VMware里绝对读不出来&#xff0c;办法就是&#xff0c;在Mac系统中转换为cdr&#xff0c;然后再转成iso&am…

Knife4j配置 ▎使用 ▎教程 ▎实例

knife4j简介 支持 API 自动生成同步的在线文档:使用 Swagger 后可以直接通过代码生成文档,不再需要自己手动编写接口文档了,对程序员来说非常方便,可以节约写文档的时间去学习新技术。 提供 Web 页面在线测试 API:光有文档还不够,Swagger 生成的文档还支持在线测试.参数和格式都…

docker部署SQL审核平台Archery

1、概述 Archery 是一个开源的 SQL 审核平台,专为数据库的 SQL 运维和管理而设计,广泛应用于企业的数据库运维工作中。其主要功能是帮助数据库管理员和开发人员实现 SQL 审核、SQL 执行、在线执行、查询、工单管理、权限控制等数据库管理相关的操作。 Archery 的主要功能包括…