linux下网络通信(udp通信协议详解)

2023-05-16

一、udp通信简介

udp是User Datagram Protocol的简称, 中文名是用户数据报协议。udp协议位于osi模型中的传输层,它是一种面向无连接的协议。udp协议并不保证数据一定能够到达对端,也不能保证数据能够按照顺序到达对端,udp数据的可靠性需要引用层来保证。

udp提供的虽然是不可靠的数据传输,但是udp在数据传输过程中延迟小、数据传输效率高,适合对可靠性要求不高的应用程序。

二、udp通信建立步骤

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FYg2OXQL-1604480407906)(A10329AC3225414C80EBF1B9DD5CE01D)]

2.1、服务器端

1)socket建立套接字,需要指定ip类型和协议类型
socket(AF_INET,SOCK_DGRAM,0);
2)bind绑定服务器ip和端口
bind(sockfd,(struct sockaddr*)&server_addr,sizeof(struct sockaddr));
3)recvfrom接收来自客户端的数据
4)sento发送数据到客户端

2.2、客户端

1)socket建立套接字,需要指定ip类型和协议类型
2)recvfrom接收来自客户端的数据
3)sento发送数据到客户端

三、udp和tcp的区别

协议UDPTCP
是否面向连接
传输可靠性不可靠可靠
传输速度
应用场合数据量少,对可靠性要求不高数据量大,对可靠性要求较高

3.1、面向连接和面向无连接

当我们需要拨打电话给某个人的时候,需要知道对方的电话号码,并且只有在对方接通电话之后才能进行正常通话,tcp面向连接就类似于拨打电话,客户端需要知道服务器的ip地址和端口并且建立连接之后才能进行正常通讯。

udp通信方式类似于对讲机,只要对方的对讲机打开,我们就可以进行语音通信,并不需要对方进行接听动作,这就是无连接。通常一个人对着对讲机说话,使用同一频段的对讲机都可以听到这个人的声音,这点也和udp广播和组播类似。

在tcp中,服务器必须开启之后,客户端才能连接上服务器,并在建立连接之后进行数据通信;而对于udp,不管服务器是否开启,udp客户端都可以正常创建并发送数据,只不过可能没有服务器接收你的数据而已。

3.2、可靠性

tcp协议提供非常可靠的数据传输方式,tcp在进行数据通信前会进行三次握手,保证通信双方能够接收对方的消息并且正确解析;在传输过程中tcp提供了重传功能,能够保证消息完整有序的到达接收端;在连接断开的时候,tcp能够通过四次握手保证最后一帧数据的完整性;

udp通信既没有三次握手和四次挥手,也没有重传机制,它只保证数据正确的发送出去,并不关心对端能不能收到,也不关心对端的数据是否接收完整或者是否按照顺序到达。

3.3、tcp和udp的优缺点和应用

tcp由于其高可靠性,多应用于数据量大并且对可靠性要求高的场合,比如http协议;udp虽然不可靠,但是传输速度很快,效率很高,而且客户端和服务器端并不相互依赖,比较适用于对及时性要求高的场合,比如早期的qq就是使用的udp协议。

四、udp协议的格式及wireshark数据包

在这里插入图片描述

我们通过客户端发送Test udp message!字符串到8099端口,使用wireshark抓取数据包如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DuuJq06r-1604480407909)(9523397E33684838B8A1837AD9F9F23E)]

可以看出udp协议的格式非常简单,它只有8个字节的首部,后面的全是数据。

五、linux下udp实例

目标:在linux下建立一个客户端和一个服务器,通过客户端发送字符串“Test udp message!”,服务器收到之后回复“Got it!”。

服务器端代码:

#include <unistd.h>
#include <pthread.h>
#include  <netdb.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/select.h>

#define UDP_PORT 8099
int main()
{
	int ret;
	int read_len = 0;
	int thread_fd;
	int sockfd;
	int server_fd;
	struct sockaddr_in server_addr;
	struct sockaddr client_addr;
	socklen_t len;
	char buffer[1024];
	
	server_addr.sin_family = AF_INET; //使用IPV4
	server_addr.sin_port = htons(UDP_PORT);//服务器端口号
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//主机可能有多个网卡,INADDR_ANY表示绑定所有网卡
	
	sockfd = socket(AF_INET,SOCK_DGRAM,0);//创建TCP,指定ip类型为IPV4
	if(sockfd < 0)
	{
		printf("socket create fail!\r\n");
		return -1;
	}
	ret = bind(sockfd,(struct sockaddr*)&server_addr,sizeof(struct sockaddr));//将socket和服务器地址绑定
	if(ret < 0)
	{
		printf("socket bind fail!\r\n");
	}
	while(1)
	{
		memset(buffer,0,sizeof(buffer));
		read_len = recvfrom(sockfd,buffer,sizeof(buffer),0,&client_addr,&len);
		printf("recv(%d):%s\r\n",read_len,buffer);//最后面如果不带\r\n可能会导致在shell中不显示数据
		if(read_len > 0)
		{
			sendto(sockfd,"Got it!",strlen("Got it!"),0,&client_addr,sizeof(client_addr));
		}
	}
	close(sockfd);
	return 0;
}

客户端代码:

#include <unistd.h>
#include <pthread.h>
#include  <netdb.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/select.h>

#define DEST_ADDR "192.168.3.15"
#define UDP_PORT 8099
int main()
{
	int ret;
	int read_len = 0;
	int sockfd;
	int server_fd;
	struct sockaddr_in dest_addr;
	struct sockaddr src_addr;
	socklen_t len;
	
	dest_addr.sin_family = AF_INET; //使用IPV4
	dest_addr.sin_port = htons(UDP_PORT);//服务器端口号
	dest_addr.sin_addr.s_addr = htonl(INADDR_ANY);//主机可能有多个网卡,INADDR_ANY表示绑定所有网卡,适用于本地通信
	//dest_addr.sin_addr.s_addr = inet_addr(DEST_ADDR);//适用于局域网通信
	
	sockfd = socket(AF_INET,SOCK_DGRAM,0);//创建TCP,指定ip类型为IPV4
	if(sockfd < 0)
	{
		printf("socket create fail!\r\n");
		return -1;
	}
	while(1)
	{
		char buffer[1024] = "Test udp message!";
		ret = sendto(sockfd,buffer,strlen(buffer),0,&dest_addr,sizeof(dest_addr));
		if(ret < 0)
		{
			printf("sendto error\r\n");
			continue;
		}
		memset(buffer,0,sizeof(buffer));
		read_len = recvfrom(sockfd,buffer,sizeof(buffer),0,&src_addr,&len);
		printf("recv:%s\r\n",buffer);
		sleep(1);
	}
	close(sockfd);
	return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux下网络通信(udp通信协议详解) 的相关文章

  • 如何在 Bash 中给定超时后终止子进程?

    我有一个 bash 脚本 它启动一个子进程 该进程时不时地崩溃 实际上是挂起 而且没有明显的原因 闭源 所以我对此无能为力 因此 我希望能够在给定的时间内启动此进程 如果在给定的时间内没有成功返回 则将其终止 有没有simple and r
  • 删除 Git 存储库,但保留所有文件

    在我使用 Linux 的过程中的某个时刻 我决定将我的主目录中的所有内容都放入源代码管理中是个好主意 我不是在问这是否是一个好主意 我是在问如何撤销它 删除存储库的原因是我最近安装了 Oh My Zsh 而且我非常喜欢它 问题是我的主目录有
  • 需要一些建议来开始在 ARM(使用 Linux)平台上编程

    我 也许 很快就会在托管 Linux 发行版的 ARM 平台上工作 我不知道哪个发行版 我知道该项目涉及视频流 但我无法告诉你更多信息 其实我只收到通知 还没见到任何人 我从来没有在这样的平台上工作过 所以我的想法是在项目开始之前进行测试
  • 如何在基于 Linux 的系统上的 C 程序中使用 mqueue?

    如何在基于 Linux 的系统上的 C 程序中使用 mqueue 消息队列 我正在寻找一些好的代码示例 可以展示如何以正确且正确的方式完成此操作 也许是一个操作指南 下面是一个服务器的简单示例 该服务器接收来自客户端的消息 直到收到告诉其停
  • 进程退出后 POSIX 名称信号量不会释放

    我正在尝试使用 POSIX 命名信号量进行跨进程同步 我注意到进程死亡或退出后 信号量仍然被系统打开 在进程 打开它 死亡或退出后是否有办法使其关闭 释放 早期的讨论在这里 当将信号量递减至零的进程崩溃时 如何恢复信号量 https sta
  • 监视目录的更改

    很像一个类似的问题 https stackoverflow com questions 112276 directory modification monitoring 我正在尝试监视 Linux 机器上的目录以添加新文件 并希望在这些新文
  • 如何构建任务“gems:install”

    我正在将 Rails 应用程序部署到 Linux 服务器 并且缺少一些 rake 任务 包括 rake gems install 和 rake db 我正在运行来自 GEM 的 Rails 2 3 4 为什么是这样 我该如何解决 我可以以某
  • Capistrano 3 部署无法连接到 GitHub - 权限被拒绝(公钥)

    我使用 Capistrano v3 和 capistrano symfony gem 设置了以下部署脚本 我正在使用 Ubuntu 14 4 部署到 AWS EC2 实例 我正在连接从 AWS 下载的 pem 文件 我的deploy rb中
  • git 错误:无法处理 https

    当我尝试使用 git clone 时https xxx https xxx我收到以下错误我不处理协议 https 有人可以帮我吗 完整消息 dementrock dementrock A8Se git 克隆https git innosta
  • Mcrt1.o和Scrt1.o有什么用?

    我坚持使用以下两个文件 即 Mcrt1 o 和 Scrt1 o 谁能帮我知道这两个文件的用途 如何使用它 我们以 gcrt1 o 为例 在使用 pg 选项编译进行性能测试时非常有用 谢谢 表格的文件 crt o总是 C 运行时启动代码 大部
  • Python 脚本作为 Linux 服务/守护进程

    Hallo 我试图让 python 脚本作为服务 守护进程 在 ubuntu linux 上运行 网络上存在多种解决方案 例如 http pypi python org pypi python daemon http pypi python
  • 从 systemd bash 内联脚本创建 filename_$(date %Y-%m-%d)

    我正在尝试执行systemd计时器并希望将执行脚本的输出保存在每个日期的文件中 这是我的ExecStart脚本中的 service file ExecStart bin bash c echo date Y m d gt gt home u
  • Awk - 计算两个文件之间的每个唯一值和匹配值

    我有两个文件 首先 我尝试获取第 4 列中每个唯一字段的计数 然后匹配第二个文件的第二列中的唯一字段值 File1 第 4 列的每个唯一值和 File2 第 2 列包含我需要在两个文件之间匹配的值 所以本质上 我试图 gt 如果 file2
  • 如何从 PROC 获取有关子进程的信息

    我正在尝试编写一个以几个进程作为参数的程序 然后父进程执行每个子进程并打印出一些相关的统计信息 示例 generate ls l 将生成一个程序 打印出有关 ls l 的一些统计信息 特别是其系统时间 用户时间和上下文切换次数 我不想使用
  • vagrant ssh -c 并在连接关闭后保持后台进程运行

    我正在编写一个脚本来启动和后台流浪机器内的进程 似乎每次脚本结束和 ssh 会话结束时 后台进程也会结束 这是我正在运行的命令 vagrant ssh c cd vagrant src nohup python hello py gt he
  • 在 Ubuntu 中找不到 X11/Xlib.h

    我试图在 Linux 上使用 open gl 编写一个相当简单的程序 但在编译时它说 编译拇指 egl 我对 GL 完全陌生 不知道出了什么问题 快速搜索使用 apt search Xlib h 打开 libx11 dev 包 但纯 Ope
  • Raspberry 交叉编译 - 执行程序以“分段错误”结束

    我有一个自己编写的程序 我想从我的 x86 机器上为 Raspberry Pi 构建它 我正在使用 eclipse 生成的 makefile 并且无法更改此内容 我已经阅读了 CC for raspi 的教程 Hackaday 链接 htt
  • C:如果文件描述符被删除,阻塞读取应该返回

    我正在以阻塞的方式从设备 文件描述符中读取 可能会发生这样的情况 在不同的线程中 设备被关闭并且文件描述符被删除 不幸的是 读取没有返回或注意到并且一直阻塞 作为一种解决方法 我可以使用 select 作为超时来执行 while 循环 如果
  • 如何将后台作业的输出分配给 bash 变量?

    我想在 bash 中运行后台作业并将其结果分配给一个变量 我不喜欢使用临时文件 并且希望同时运行多个类似的后台任务 root root var echo hello world root root echo var hello world
  • 这种 bash 文件名提取技术有何用途?

    我有一部分 bash 脚本正在获取不带扩展名的文件名 但我试图了解这里到底发生了什么 是做什么用的 有人可以详细说明 bash 在幕后做了什么吗 如何在一般基础上使用该技术 bin bash for src in tif do txt sr

随机推荐

  • QCustomplot(五)QCPAxisRect进行子绘图

    子绘图是比较复杂的 xff0c 你几乎需要掌握QCustomPlot所有类及其含义 那么需要掌握的类有 xff1a QCPAxis 描述轴行为 xff0c 轴需要依赖QCPAxisRectQCPAxisRect 描述矩形区域 xff0c 区
  • 关于C/C++的换行

    可以分为两种情况 xff1a 代码换行长字符串换行 一 C C 43 43 代码换行直接用enter键换行 xff0c 同时注意关键字不要切割 xff1a span class token keyword bool span a span
  • 31线性变换及其矩阵

    一 线性变换的概念 线性变换是数学中一种特殊的映射 xff0c 它具有将向量空间中的元素转换到另一向量空间元素的功能 xff0c 同时也保持了变换前后向量的线性不变的性质 线性变换的数学表达式如下 xff1a T c
  • 30奇异值分解

    在讲SVD之前 xff0c 我们先来看看计算是如何存储一个灰度图的 灰度图会被分割成一块块的小灰度像素 xff0c 然后进行存储 xff0c 数值的大小表示灰度的程度 一个灰度像素用8位进行存储 xff0c 也就是256种状态 xff0c
  • (二)PID控制的Anti-windup

    比例环节 xff1a 快速接近目标积分环节 xff1a 防止稳态误差微分环节 xff1a 减少振荡 被控对象可以分为两个部分 xff0c 分别是执行器 xff0c 用于产生力或者能量从而改变系统 xff0c 和处理 xff0c 比如说温控的
  • Socket的学习(一)什么是Socket?

    本文参考的是 Socket通信原理 https www cnblogs com wangcq p 3520400 html 一 TCP IP UDP是什么 xff1f TCP IP xff08 Transmission Control Pr
  • Socket的学习(二)AF_UNIX实现本地通信

    参考文章 xff1a 1 Unix Domain Socket IPC通信机制 2 How fast are Unix domain sockets 3 read 函数参数理解 一 Unix域的Socket通信及其优点 基于socket的框
  • 工程师笔记|在CMD窗口运行C语言

    cmd窗口大家可能都比较熟悉 xff0c 那如何在cmd窗口编译运行C语言程序呢 xff1f 其实很简单的 xff0c 只需要下载一个C C 43 43 编译器 xff0c 添加一下环境变量 xff0c 之后就能在cmd窗口中编译运行C语言
  • 推挽输出与开漏输出

    推挽输出 要理解推挽输出 xff0c 首先要理解好三极管 xff08 晶体管 xff09 的原理 下面这种三极管有三个端口 xff0c 分别是基极 xff08 Base xff09 集电极 xff08 Collector xff09 和发射
  • 固件、驱动、软件的区别

    不管我们使用什么操作系统 xff0c 无论是 Windows macOS xff0c 还是 Linux xff0c 里面都安装了许多软件 驱动程序和固件 但是 xff0c 这三者概念有什么区别 xff1f 转载微信公众号 xff1a 良许L
  • 51单片机与STM32的区别(为何51单片机IO引脚的驱动能力弱)

    1 51单片机的特性 51单片机之所以成为经典 xff0c 成为易上手的单片机主要有以下特点 xff1a 从内部的硬件到软件有一套完整的按位操作系统 xff0c 称作位处理器 xff0c 处理对象不是字或字节而是位 不但能对片内某些特殊功能
  • I2C—读写EEPROM

    1 I2C协议简介 I2C通讯协议 Inter xff0d IntegratedCircuit 是由Phiilps公司开发的 xff0c 由于它引脚少 xff0c 硬件实现简单 xff0c 可扩展性强 xff0c 不需要USART CAN等
  • SPI—读写串行FLASH

    1 SPI协议简介 SPI协议是由摩托罗拉公司提出的通讯协议 SerialPeripheralInterface xff0c 即串行外围设备接口 xff0c 是一种高速全双工的通信总线 它被广泛地使用在ADC LCD等设备与MCU间 xff
  • C语言中的关键字应用技巧(volatile、const、struct/union、_ _预定义_ _、#/##、void/void*、weak)

    嵌入式C开发关键字的应用技巧 1 volatile volatile修饰表示变量是易变的 xff0c 编译器中的优化器在用到这个变量时必须每次都小心地从内存中重新读取这个变量的值 xff0c 而不是使用保存在寄存器里的备份 xff0c 有效
  • 一文弄懂GPIO不同模式之间的区别与实现原理

    GPIO全称General Purpose Input Output xff0c 即通用输入 输出 其实GPIO的本质就是芯片的一个引脚 xff0c 通常在ARM中所有的I O都是通用的 不过 xff0c 由于每个开发板上都会设计不同的外围
  • printf()是如何与UART外设驱动函数“勾搭”起来的?

    今天给大家分享的是IAR下调试信息输出机制之硬件UART外设 在嵌入式世界里 xff0c 输出打印信息是一种非常常用的辅助调试手段 xff0c 借助打印信息 xff0c 我们可以比较容易地定位和分析程序问题 在嵌入式应用设计里实现打印信息输
  • 卡塔尔世界杯:带“芯片”的智能足球亮相!背后藏着哪些技术原理?

    2022年卡塔尔世界杯正式开幕 xff01 揭幕战上 xff0c 厄瓜多尔队以2 0的比分击败东道主卡塔尔队 xff0c 取得本届世界杯的首场胜利 本场比赛后 xff0c 世界杯东道主首战不败的纪录就此作古 xff0c 这一消息也引发足球圈
  • 串口通信详解

    一 串口通讯简介 串口通信 Serial Communications 的概念非常简单 xff0c 串口按位 bit 发送和接收字节 尽管比按字节 byte 的并行通信慢 xff0c 但是串口可以在使用一根线发送数据的同时用另一根线接收数据
  • C++类详解(public、private、protected)

    二 C 43 43 类的声明 类使用class关键字声明 xff0c 声明方法如下 xff1a class 类名 xff1a public 公有成员 int num private 私有成员 int age protected 保护成员 i
  • linux下网络通信(udp通信协议详解)

    一 udp通信简介 udp是User Datagram Protocol的简称 xff0c 中文名是用户数据报协议 udp协议位于osi模型中的传输层 xff0c 它是一种面向无连接的协议 udp协议并不保证数据一定能够到达对端 xff0c