关于UDP双向通信原理解释与范例

2023-05-16

注:本文不提供UDP通信的头文件

OK.Let‘s do it; 

首先,我们需要了解什么叫做UDP,之前博主有些过TCP的通信范例,我们可以了解到TCP通信是一个稳定的,可以进行双边通信的方式。同样附带进程or线程or IO多路复用技术则可以实现一个服务器对接多个客户端

UDP,是可以通过自身绑定的端口号直接实现一个服务器对接多个客户端。当然,我也不是说它是很牛逼的,这个技术固然很好,但也有缺点。UDP本身的网络通信是不稳定的,从概率学上讲使用这种技术一定会在某个时间,某个地点,丢失某些数据。SO,I'm not advice use it. BUT,因为总有一些同学希望可以了解这种通信,那么就浅浅的说亿下下。

-------------------------------------我是分割线-------------------------------------------

一,关于UDP与TCP之前通信方式的建立区别。

首先来讲一下,TCP建立流程:如下

TCP服务器:【创建自身socket文件】->【绑定自身的IP号与端口号】->【建立监听线】->【接收外部发来的接入请求or数据】->【开始收or发数据】 对应的函数分别为 socket、bind、listen、accept、(send | recv)

TCP客户端:【创建socket】->【搜寻ip和port请求接入】->【开始收or发数据】对应的函数为: socket 、connect、(send | recv) 

----------------------------------我是分割线----------------------------------------------------------

接下来讲一下,UDP建立流程:如下

UDP服务器:【创建自身socket文件】->【绑定自身的端口号】->【开始收or发数据】对应的函数为socket、bind、(sendto | recvfrom)

UDP客户端:【创建自身socket文件】->【搜寻port】->【开始收or发数据】对应的函数为socket、(sendto | recvfrom)

----------------------------------------------------------------------------------------------------

对比一下,是不是少了accept和listen函数,其次收发数据换成了sendto和recvfrom函数。其他的都一样。

但其实大体上思路没有变化,只是把accept和listen函数里面的参数加入到了原本的(send | recv) 两个函数中,然后换个名字就行了。

那么我们可以看一下这几个函数的详细信息,如下:send

 举例子:将缓冲区buf里面的内容发送至通过socket链接的对端

char buf[20]={0};
send(socket,buf,sizeof(buf),0);

同理recv(socket,buf,sizeof(buf),0);就是通过socket链接对端发送数据放到buf里

再来看一下关于sendto的说明:sendto

来,举个栗子:结构体BB捕捉的IP地址和端口号通过socket链接,再把buf里面的内容发出去

char buf[20]={0};
sendto(socket,buf,strlen(buf),0,(struct sockaddr *)&BB,client); 

同理recvfrom(socket,buf,sizeof(buf),0,(struct sockaddr *)&BB,&client);就是socket链接的对端发送数据放到buf里。结构体BB为固定端口号,IP不固定。

 -----------------------------------我是分割线---------------------------

听迷糊了是不?来,上实际例子和操作。

二,关于UDP通信实际操作

如下:UDP服务器 

#include "../../all.h"
int main(int argc, const char *argv[])
{
	int fa=socket(AF_INET,SOCK_DGRAM,0); //创建UDP类型套接字  使用协议为sock_dgram
	if(fa<0){printf("UDP套接字文件创建失败!\n"); return -1;}
	struct sockaddr_in AA; //创建用于自身绑定的IP和端口号结构体文件
	AA.sin_addr.s_addr =INADDR_ANY;  //服务器自动接收IP地址进行绑定
	AA.sin_port = htons(atoi(argv[1]));
	AA.sin_family = AF_INET;
	int fb=bind(fa,(struct sockaddr*)&AA,sizeof(AA));
	if(fb<0){printf("绑定失败!\n");return -1;} printf("绑定成功!\n");
	char buf[20]={0};  //设定缓冲区用于接收客户端发来的连接请求数据
	while(1)  //保证接收多个客户可重复取到
	{
		struct sockaddr_in BB; //用于接收客户端发送的连接数据orIP和端口号的结构体
		memset(&BB,0,sizeof(BB));
		int client =sizeof(BB);
		recvfrom(fa,buf,sizeof(buf),0,(struct sockaddr*)&BB,&client);
		printf("客户端IP =%s  端口号=%d\n",inet_ntoa(BB.sin_addr),ntohs(BB.sin_port));
		printf("buf=%s",buf);
		printf("请输入需要广播的内容:");
		fgets(buf,sizeof(buf),stdin);
		sendto(fa,buf,strlen(buf),0,(struct sockaddr *)&BB,client); //发送广播内容
	}
	close(fa);
	return 0;
}

注*:服务器设计是先接收接入的IP和UDP信息,然后服务器发送一个消息至刚才接入的客户端然后其他客户端回复一个消息才能接收到服务器下一个消息

翻译:(哪个客户端想呼叫服务器了,就连接服务器。连接完毕后服务器必须在下一个客户端抢占通传输通道前发送消息。否则服务器发送的数据会搞错成最近一个接入的客户端)

如下:UDP客户端

#include "../../all.h"
int main(int argc, const char *argv[])
{
	int fa = socket(AF_INET,SOCK_DGRAM,0); 
	if(fa<0){printf("UDP套接字文件创建失败!\n");return -1;}
	struct sockaddr_in AA; //创建要用的结构体,用于捕捉相应的端口号和IP号
	AA.sin_addr.s_addr = inet_addr(argv[1]);
	AA.sin_port = htons(atoi(argv[2]));
	AA.sin_family = AF_INET;
	char buf[20]={0};
	while(1)
	{   int len = sizeof(AA);
		memset(buf,0,sizeof(buf));
		printf("输入内容:");
		fgets(buf,sizeof(buf),stdin);
		sendto(fa,buf,sizeof(buf),0,(struct sockaddr*)&AA,sizeof(AA));
		memset(buf,0,sizeof(buf));
        recvfrom(fa,buf,sizeof(buf),0,(struct sockaddr *)&AA,&len);
		printf("%s\n",buf);
	}
	close(fa);
	return 0;
}

 再来看实际操作:

 但本次所写的代码只能实现1:1的回复,即你发一句,我收一句。我发一句,你收一句。

所以该UDP写法存在局限性,无法实现像QQ聊天框那种情况,但是可以把这个代码嵌入到普通的对讲机中,相对而言还是不错的。

每次服务器发送的对象,只能是上一个发送数据的客户端,因为发送后我们清除了接收结构体里面携带的客户端IP和端口号所以服务器端发送时,无法精准捕捉回复的具体对象

但是他也有优点,就是多对一便捷!!!

好啦,本次讲解就到此结束,若有不明白,有错的地方,欢迎私聊博主纠正。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于UDP双向通信原理解释与范例 的相关文章

  • 【STM32学习笔记】(5)—— STM32工程添加源文件和头文件

    向工程目录里创建头文件和源文件 STM32的工程文件构成较为复杂 xff0c 同时为STM32工程文件添加源文件和头文件也是较为复杂的 xff0c 下面就由此文章来介绍怎么给STM32工程添加源文件 xff08 c xff09 与头文件 x
  • 在STM32中使用printf函数

    一 目的 利用printf函数使得输出打印到串口中 二 工作原理 我们在C语言中为什么能够调用printf函数打印数据到控制台中 xff0c 那是因为printf函数又调用了fputc 函数 那么我们我们可不可以说printf函数之所以能够
  • 电赛备赛日记(一):K210与STM32串口通信

    拖更了n久的备赛日记终于来啦 xff0c 最近实现了关于K210图像识别并将所需数据 xff08 即目标类别 xff0c 目标在图像中的加权坐标 xff09 其中 xff0c 加权坐标指K210识别到的目标并框出的框的宽和高与框左上顶点的坐
  • 实验作业2(数组)

    64 TOC实验题目2 xff1a 某公司生产5种产品 xff0c 每周记录生产的每种产品数量和销售数量 每个月月末 xff0c 公司将对其生产规划进行评估 该评估需要以下一个或多个信息 每周生成和销售的数量 xff1b 所有生产产品的总量
  • 函数作业

    仅供交流 xff0c 禁止抄袭 实验一 求序列的和 问题描述 求Y 61 1 1 2 43 1 3 1 4 43 1 2 n 的前n项之和 输入形式 从键盘输入n 输出形式 输出n项和 按四舍五入的方式精确到小数点后第二位 样例输入 30
  • Windows下MySQL安装及配置

    目录 1 MySQL下载2 MySQL配置 mysql版本 xff1a 5 7 注 xff1a 1 现在最新的mysql版本是8 0 xff0c 但是一般安装软件都不推荐安装最新版本的 xff0c 因为可能会有一些错误无法预见 xff0c
  • SLAM遇到的问题及技巧

    文章目录 1 rosbag太大了 xff0c 打不开2 机器人的三维变换roslaunch的node强制关闭了 xff0c exit code 11 1 rosbag太大了 xff0c 打不开 以LZ4格式压缩 rosbag compres
  • 关于螺旋数组的讨论

    下面收集了几种可能的螺旋数组形式以及相应的主代码 供大家学习参考 给定N的值 xff0c 从矩阵的左上角输出顺时针螺旋矩阵 例如N 61 4时 xff0c 输出 xff1a 1 2 3 4 12 13 14 5 11 16 15 6 10
  • 动态链接库dll详解

    动态链接库概述 DLL就是整个Windows操作系统的基础 动态链接库不能直接运行 xff0c 也不能接收消息他们是一些独立的文件 Windows API中的所有函数都包含在DLL中 其中有三个最重要的DLL kernel32 dll xf
  • stm32中printf重定向

    先上代码 加入以下代码 支持printf函数 而不需要选择use MicroLIB if 1 pragma import use no semihosting 标准库需要的支持函数 struct FILE int handle FILE s
  • STM32F103RCTX 串口USART 不定长接收

    串口不定长接收的方法有多种 xff0c 这里我所介绍的是通过设置IDLE中断来检测串口是否接收完毕 xff0c 从而结束串口接受中断 1 首先设置串口 xff0c 如下图所示 xff1a 2 使用IDLE中断检测 xff0c 所以需要开启对
  • ROS通信模式/动作编程(设置收发节点,使小海龟移动到指定位置)以及分布式通信

    文章目录 一 话题 服务模式编程1 1 创建工作空间1 1 1 创建ROS工程包1 1 2 在工作区编译工程包 1 2 话题模式编程1 2 1 创建通信的收 发节点1 2 1 1 在src目录中创建一个发布节点1 2 1 2 在src目录中
  • Ubuntu18.04安装ros(顺利解决 sudo rosdep init 与 rosdep update 存在的问题,附保姆级图文流程)

    Ubuntu18 04 xff08 Ubuntu20 04 xff09 安装ros 顺利解决 sudo rosdep init 与rosdep update 存在的问题 xff0c 附保姆级图文流程 前言 安装了很多次 xff0c 东拼西凑
  • linux命令发送接口请求

    curl k X POST H 34 Accept Encoding gzip deflate 34 H 34 Content type application 34 H 34 x www form urlencoded UTF 8 34
  • UDP协议及编程

    UDP协议 UDP是无连接的 xff0c 即发送数据之前不需要连接 xff0c 因此减少了开销和发送数据之间的时延 UDP使用尽最大努力交付 xff0c 即不保证可靠交付 xff0c 因此主机不需要维持复杂的连接状态表 UDP是面向报文的
  • 24.STM32的IO口扩展PCF8574

    1 IO口扩展芯片 PCF8574是一款带IIC总线 xff0c 可使大多数MCU实现远程I O 口扩展 该器件包含一个8位准双向口和一个IIC总线接口 xff08 通信接口IIC xff0c 2根线可以扩展为8个口 xff09 PCF85
  • 网络编程(二)基础预备知识掌握

    网络编程预备知识 socket 是一种编程接口也是一种文件描述符 xff08 套接字 xff09 可用于 TCP UDP IPX通信 socket的类型 流式套接字 xff08 SOCK STREAM xff09 xff1a 提供一种面向连
  • 使用USTC-TK2016工具对USTC-TFC2016数据集进行处理——报错解决记录

    USTC TK2016数据处理工具 xff1a https github com yungshenglu USTC TK2016 USTC TFC2016数据集 xff1a https github com yungshenglu USTC
  • C++避免头文件重复包含问题

    避免头文件重复包含的方法 xff0c 通常有两种做法 xff1a 条件编译和 pragma once 条件编译就是通常的 ifndef XXX H define XXX H endif ifndef XXX H 表示 xff0c 如果没有包
  • c++ 调用yolov3-yolov4

    ifdef WIN32 define OPENCV define GPU endif include lt iostream gt include lt windows h gt include 34 yolo v2 class hpp 3

随机推荐

  • 一文搞懂UART、RS232、RS485、TTL等常用的接口与协议

    常用的接口与协议 PC机常用的按照接口数量细分为A型 xff08 15针 xff09 xff0c B型 xff08 25针 xff09 xff0c C型 xff08 37针 xff09 xff0c D型 xff08 50针 xff09 xf
  • 解决头文件重复包含与结构体未定义的问题

    一 养成良好的编程习惯 1 保证h文件的纯洁性 xff1a 尽量一个c文件对应一个h文件 xff0c 不要h文件包含许多h文件 这样可以优化编译速度且避免出现h文件中某个结构体之类未定义 xff0c 先在上个h文件中使用的错误 2 对于变量
  • Nokia 5110液晶屏显示模块的使用与开发

    Nokia 5110液晶屏显示模块 我们先来看看他的参数 nbsp 在深入研究连接和示例代码之前 让我们首先看一下其Pinout nbsp RST nbsp 针复位显示 它是低电平有效引脚 您可以通过将其拉低来重置显示 您也可以将此引脚连接
  • mongodb的文档的分页查询

    统计查询使用count xff08 xff09 方法 xff1a 统计comment集合的所有的记录数 xff1a db comment count 分页列表查询 xff1a 可以使用limit xff08 xff09 方法来读取指定数量的
  • 前后端分离项目的部署

    本次项目的项目架构图 xff1a Nginx主要部署的是 项目的静态资源 xff0c 即前端项目 通过Nginx的反向代理 xff0c 将请求发给Tomcat服务器 然后获取数据通过MySQL的主从复制 xff0c 主库负责更新数据 xff
  • echarts基本用法

    目录 tooltip 设置提示框信息 图表的提示框组件 legend 图例组件 toolbox 工具箱组件 可以另存为图片等功能 grid 网格配置 grid可以控制线型图 柱状图 图表大小 xAxs 设置x轴的相关配置 y轴同理 seri
  • java实现UDP通信传输信息

    实现UDP通信要依靠 DatagramPacket对象进行实现 UDP协议的相关介绍 xff1a UDP传输分为 服务端 和客户端 服务端发送消息 客户端接收消息 xff0c 服务端需要知晓客户端的 IP和所监听的端口号 话不多说直接上代码
  • MySQL篇之动态建表。

    在日常开发中 xff0c 可能会出现 动态配置的一些情况 xff0c 此时存储动态配置的一些数据时就需要动态建表了 xff0c 家人们可以选则两种方案 一种是采用mybatis的mapper xml文件里面使用 语句进行创建 二就是使用da
  • IDEA 2020.2 配置Tomcat服务器

    1 创建一个工程 2 右键项目名称 xff0c 选择 add framwork support 3 选中Web Application xff0c 默认勾选创建web xml 目录结构如下 4 点这两个地方中的任意一个 xff0c 添加配置
  • Java笔记之markdown语法

    狂神说Java系列视频笔记 本文章是作者学习B站系列视频 狂神说Java 的记录笔记与心得 xff0c 创作不易 xff0c 希望能够得到您的支持 1 Markdown的基本语法与使用 Markdown是当下一种较为流行的一种写作方法 通过
  • Java之数组专题

    文章目录 Java基础之数组专题数组的定义数组的声明与初始化数组元素的访问内存分析数组的使用For Each 循环数组作方法入参冒泡排序 多维数组稀疏数组 Java基础之数组专题 本文章是作者学习B站系列视频 狂神说Java 与经典书籍 J
  • Java封装详解

    Java类和对象 本文章是作者学习B站系列视频 狂神说Java 与经典书籍 Java核心技术 的记录笔记与心得 xff0c 创作不易 xff0c 希望能够得到您的支持 Java的构造器 Java的构造器 在用Java自定义类时 xff0c
  • C++ primer plus第七章习题中遇到的cin与cin.get问题

    cin gt gt 与cin get 是cpp程序常用到的输入函数 xff0c 近日在编写一道简单的习题时 xff0c 对二者产生了一些疑问 xff08 题目来源 C 43 43 primer plus 中文版习题第七章第六题 xff09
  • Leetcode部分经典链表题解析(涉及链表的反转、排序、合并、移除元素、成环、相交等操作)

    链表相关问题 第206题 反转链表 要求 xff1a 将给定链表进行反转操作 xff0c 第一个结点作为尾结点 xff0c 第二个结点指向第一个节点 xff0c 以此类推 xff0c 使得原链表的尾结点作为答案的头结点 思路一 xff1a
  • Linux报错:terminate called after throwing an instance of ‘std::regex_error‘ what(): regex_error

    文章目录 1 报错 xff1a 2 源码 3 原因 xff1a 4 解决办法 xff1a 5 运行成功 xff1a 1 报错 xff1a Linux中测试cpp httplib时出现报错std regex error xff0c 但源码中并
  • Redis学习笔记(狂神说)

    狂神视频地址 xff1a https www bilibili com video BV1S54y1R7SB Nosql概述 为什么要用Nosql 1 单机Mysql的年代 DAL xff1a 数据库访问层 在90年代 xff0c 一个基本
  • gazebo地图构建

    搭建地图环境是gazebo的基础功能 打开gazebo 可以在终端输入指令 打开的时候一定要有sudo xff0c 不然有可能在后面保存的时候出现画面卡住不动的情况 span class token operator span sudo g
  • Linux Ubuntu18.04安装微信

    最近做双系统 xff0c 在Ubuntu里下载微信时发现微信没有光网里没有开发Linux版本的微信 xff0c 找到了一些使用网页版登录微信的教程 xff0c 按着网上的教程做下来会的到一个如下的微信图标 打开扫描二维码后无法登录 可以在其
  • 虚拟机Ubuntu18.04 使用usb_cam调用笔记本摄像头

    虚拟机搭载Ubuntu18 04调用笔记本的摄像头 xff08 踩坑以及解决方法 xff09 一 建立工作空间 xff08 略 xff09 这里我建立的工作空间名称是catkin ones 二 下载usb cam包并进行编译 git clo
  • 关于UDP双向通信原理解释与范例

    注 本文不提供UDP通信的头文件 OK Let s do it 首先 我们需要了解什么叫做UDP xff0c 之前博主有些过TCP的通信范例 xff0c 我们可以了解到TCP的通信是一个稳定的 xff0c 可以进行双边通信的方式 同样附带上