UDP通信

news/2024/5/18 15:13:45 标签: udp, 单片机, 网络协议

UDP通信

  • 1、UDP
  • 2、UDP通信流程
  • 3、UDP服务器代码
  • 4、UDP客户端代码
  • 5、应用场景

1、UDP

/*
udp传输层协议,和tcp是一样的
特点:
	面向无连接的,不安全的,报式传输协议
	1.无连接:ldp通信的时候不需要connect
		1) 通信不需要建立连接
		2) 如果想给对方发送数据,只需要指定对方的IP和端口
	2. udp会丢包
		1) 数据丢失了就没有了,没有数据校验机制
		2) udp不会丢失一部分数据,丢就是全丢,不丢就是一点不不丢
	3.报式:
		发送端发送多少数据,接牧端接收多少数据|
*/

2、UDP通信流程

udp通信过程中,服务器和客户端做的操作几乎是一样的
在这里插入图片描述

  1. 服务器端
// 1. 创建一个通信的套接字   AF_INET使用IPv4 
int cfd = socket(AF_INET,SOCK_DGRAM,0); //通信使用udp
// 2.通信的套接字和本地的IP和端口绑定
// 绑定的目的:程序启动之后不主动发送数据,先接收数据,就需要绑定端口
// 如果不手动绑定端口,就会自动绑定端口,主动发送数据,可以自动绑定端口
struct sockaddr_in addr ;
bind(cfd, (struct sockaddr* )&addr, sizeof(addr) );
//  3.通信
接收数据:recvfrom( ) ;
发送数据:sendto();
// 4. 关闭通信的文件描述符
close(); 
  1. 客户端
// 1. 创建一个通信的套接字  
int cfd = socket(AF_INET,SOCK_DGRAM,0); //通信使用udp
// 2.通信的套接字和本地的IP和端口绑定
// 绑定的目的:程序启动之后不主动发送数据,先接收数据,就需要绑定端口
// 如果不手动绑定端口,就会自动绑定端口
struct sockaddr_in addr ;
bind(cfd, (struct sockaddr* )&addr, sizeof(addr) );
//  3.通信
接收数据:recvfrom( ) ;
发送数据:sendto();
// 4. 关闭通信的文件描述符
close();
  1. 操作函数
//接收数据
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

//接收和发送数据的函数默认是阻塞的
//接收数据
ssize_t recvfrom( int sockfd, void *buf, size_t len, int flags,
					struct sockaddr *src_addr, socklen_t *addrlen) ;
参数∶
	- sockfd:通信的文件描述符
	- buf:指向一块有效内存地址,存储接收的数据
	- len:参数buf指向的内存大小
	- flags:使用默认属性,指定为0即可
	- src_addr:传出参数,保存发送端的地址信息(IP和端口)->大端(网络字节序)
		- 对发送端的地址不感兴趣,可以指定为NULL
	- addrlen:传入传出参数,类似于accept()最后一个参数
		- src_addr为NULL,该参数也指定为NULL即可
返回值:
	>0:接收的字节数
	-1:失败
	
//发送数据函数
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
				const struct sockaddr *dest_addr, socklen_t addrlen);
参数:
	- sockfd:通信的文件描述符
	- buf:指向一块有效内存地址,内存中存储了待发送的数据
	- len:参数buf指向的内存中待发送的数据长度
	- flags:使用默认属性,指定为0即可
	- dest_addr:传入参数,保存接收端的地址信息(IP和端口)->大端(网络字节序)
	- addrlen:传入参数,dest_addr参数指向的内存大小
返回值:
	>0: 发送的字节数
	-1:失败
  • 通信流程总结:
    • 服务器
// 1.创建通信的套接字
int fd = socket(af_inet, sock_dgram, 0);
// 1.5 如果服务器只接受数据,需要绑定端口
bind();
// 2.通信
recvfrom();
sendto();
// 3.关闭套接宇
close():
* 客户端
// 1.创建通信的套接字
int fd = socket(af_inet, sock_dgram, 0) ;
// 1.5 如果客户端是主动发送发送数据,绑定端口可以不写(随机绑定)
// bind();
// 2.通信
recvfrom();
sendto();
// 3.关闭套接字
close():

3、UDP服务器代码

#include <stdio.h>
#include <stdlib.h>
#incIude <unistd.h>
#incIude <string.h>
#include <arpa/inet.h>
//服务器端启动之后不发送数据,先接收数据
//需要手动绑定端口
int main()
{
	// 1.创建通信的套接字
	int fd = socket(AF_INET,SOCK_DGRAM,0);
	if(fd == -1)
	{
	      perror(exit(0));
	      exit(0);
    }
	// 接收数据需要绑定固定的端口
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port= htons(8989);
	addr.sin_addr.s_addr = INADDR ANY;
	int ret = bind(fd,(struct sockaddr*)&addr,sizeof(addr));
	if(ret == -1)
	{
		perror("bind");
		exit(0);
	}
	//通信
	char ip[24];
	char buf[1024];
	struct sockaddr_in cliaddr;
	int clilen = sizeof(cliaddr);
	while(1)
	{
		//接收数据
		int len= recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr*)&cliaddr,&clilen);
		if(len==-1)
		{
			break;
		}
		printf("client ip: %s, port: %d\n",
				inet_ntop(AF_INET, &cliaddr.sin_addr.s_addr, ip, sizeof(ip)), 
				ntohs(cliaddr.sin_port));
		printf("client say: %s\n", buf);
		//回复数据
		sendto(fd, buf, strlen(len)+1, 0, (struct sockaddr*) &cliaddr, clilen);
		close(fd);
		return 0;
	}

	return 0;
}

4、UDP客户端代码

#include <stdio.h>
#include <stdlib.h>
#incIude <unistd.h>
#incIude <string.h>
#include <arpa/inet.h>
//客户端启动之后主动发送数据
//自动随机绑定端口
int main()
{

	// 1.创建通信的套接字
	int fd = socket(AF_INET,SOCK_DGRAM,0);
	if(fd == -1)
	{
	      perror(exit(0));
	      exit(0);
    }
    #if 0
	// 接收数据需要绑定固定的端口
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port= htons(8989);
	addr.sin_addr.s_addr = INADDR ANY;
	int ret = bind(fd,(struct sockaddr*)&addr,sizeof(addr));
	if(ret == -1)
	{
		perror("bind");
		exit(0);
	}
	#endif
	//通信
	char ip[24];
	char buf[1024];
	struct sockaddr_in cliaddr;
	int clilen = sizeof(cliaddr);
	//服务器地址
	struct sockaddr_in seraddr;
	seraddr.sin_family = AF_INET;
	seraddr.sin_port = htons(8989);
	inet_pton(AF_INET, "192.168.233.121",&seraddr.sin_addr.s_sddr);
	while(1)
	{
		sprintf(buf, "hello, world, %d...\n",num++);
		//发送数据,发送给服务器
		sendto(fd, buf, strlen(buf)+1, 0, (struct sockaddr*) &seraddr, sizeof(seraddr));
		memset(buf,0,sizeof(buf));
		int len= recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr*)&cliaddr,&clilen);
		if(len==-1)
		{
			break;
		}
		printf("server say: %s\n", buf);
		close(fd);
		return 0;
	}

	return 0;
}

5、应用场景

  • 数据容易丢,用在对数据没有那么敏感的场景下。
    • 用户名密码->不行
    • 文件传输->不行
    • 语言通信->可以
    • 视频聊天,视频会议->可以。
    • 屏幕共享->可以
  • 效率高
    • 不需要建立连接
    • 数据校验机制
  • 一般用于局域网,数据丢包比较少,广域网,网络环境不好容易丢包
    • qq处理文件传输使用的是tcp,其他都是udp
    • 比较大的公司,有一个人力和财力,会在应用层对udp通信的数据包进行校验
      • 应用层->检验udp数据,让rdp类似于tcp,但是效率高
      • 传输层> udp
      • 网络层
      • 网络接口层

http://www.niftyadmin.cn/n/5032934.html

相关文章

【Transformer系列】深入浅出理解Transformer网络模型(综合篇)

一、参考资料 The Illustrated Transformer 图解Transformer&#xff08;完整版&#xff09; Attention Is All You Need: The Core Idea of the Transformer transformer 总结(超详细-初版) Transformer各层网络结构详解&#xff01;面试必备&#xff01;(附代码实现) 大语言…

log4j2使用的bug

项目场景&#xff1a; 领导今天给了一个需求&#xff0c;是关于日志的&#xff0c;需要在日志中打印出sql语句 问题描述 我根据网上的教程&#xff0c;案例改了很多版&#xff0c;有xml写法的&#xff0c;有在application.yml改mybatis日志输出设置的&#xff0c;如 原因分析…

儿童用白炽灯和护眼灯哪个好一点?适合儿童使用的台灯推荐

现今的近视已然成为普遍现象&#xff0c;而且有往低年龄段发展的趋势。对孩子来说&#xff0c;日常孩子在家里抹黑看书&#xff0c;晚上看手机不开灯等习惯&#xff0c;都会导致眼睛受损&#xff0c;继而引发近视。所以给孩子挑选一款合适的台灯还是很重要的&#xff01;那么儿…

2023年 python结合excel实现快速画图(零基础快速入门)

目录 1.适用人群 2.环境配置 3.基本用法 3.1 数据读取 3.2 数据分析 3.3 数据组装 3.4 制表&#xff1a; 4.快速提升 5.效果展示 1.适用人群 电脑有python环境&#xff0c;会python基本使用&#xff0c;需要短时间内完成大量画图任务的数据分析的人群。&#xff08;有…

uniapp开发小程序中实现骨架屏

第一步&#xff1a;小程序中实现骨架屏在微信开发者工具中点击生成骨架屏&#xff1a; 第二步&#xff1a;复制html代码&#xff0c;到骨架屏vue组件汇中再把之前写的样式代码引入进去&#xff1a; import ../../pages/user/user.css; 第三步&#xff1a;组件中引入骨架屏&am…

再想一想GPT

一 前言 花了大概两天时间看完《这就是ChatGPT》&#xff0c;触动还是挺大的&#xff0c;让我静下来&#xff0c;认真地想一想&#xff0c;是否真正理解了ChatGPT&#xff0c;又能给我们以什么样的启发。 二 思考 在工作和生活中&#xff0c;使用ChatGPT或文心一言&#xff0c;…

再战SDRAM与资料整理。

总之只要阅读操作手册&#xff0c;按照时序来&#xff0c;完全不难&#xff01; 器件记录&#xff1a; 小梅哥AC620上SDRAM&#xff1a;M12L2561616A-6TG2T 其的存储空间为16M*16256MB&#xff0c;第二行的数字则与其速度等级有关&#xff1b;其分为&#xff1a; 4bank*16bit…

windows下mysql的高可用方案

PS:理论上linux下也可以使用这种方案 环境准备&#xff1a; 首先准备两台电脑&#xff0c;全部安装MySQL&#xff0c;然后分别查看一下ip地址&#xff0c;我的两个ip分别是&#xff1a; 192.168.25.134&#xff08;简称134&#xff09; 192.168.25.135&#xff08;简称135&a…