UDP传输协议Linux C语言实战

文章目录

  • 1.UDP简介
    • 1.1特点
    • 1.2 UDP协议头部格式
      • 1.2.1 **UDP头部**:
      • 1.2.2 **头部意义**:
      • 1.2.3 **头部参数**:
    • 1.3 UDP数据长度控制
    • 1.4 UDP协议建立框架
  • 2. 函数介绍
    • 2.1 sendto函数
    • 2.2 recvform函数
    • 2.3 其他函数
  • 3.实例
    • 3.1 通用结构体、IPV4结构体、IPV6结构体
    • 3.2 框架搭建
      • 3.2.1 client
      • 3.2.2 server
    • 3.3 服务端和客户端编写
      • 3.3.1 client_udp.c
      • 3.3.2 sever_udp.c
      • 3.3.3 终端结果
  • 4.总结

摘要:这篇文章是对UDP传输协议的讲解,包括基础知识、主要函数,最后通过在linux上用C语言建立客户端和服务端实例对UDP的认识更加深刻。
关键词:UDP、sendto、recvfrom。

1.UDP简介

1.UDP(User Datagram protocol)传输协议是TCP/IP网络协议下,传输层的一中面向报文传输方式。

1.1特点

1.无连接特性:传输时不用建立连接,服务端也不用做出响应。
2. 不可靠传输:没有TCP那样复杂,发送端只管发送数据,不会管接收端的感受,真是个无情的man。
3. 快速传输:由于 UDP 没有连接建立和可靠传输机制带来的开销,它可以非常快速地发送数据。
4.面向数据报:应用层发送多少,UDP传输层就给网络层发送多少数据。

1.2 UDP协议头部格式

在这里插入图片描述

1.2.1 UDP头部

UDP头部没有TCP头部那么复杂,只占了8个字节,而TCP头部最小20各字节,根据可选项参数还能扩展到60个字节,TCP头部长度标识只占4位,但是TCP头部的每一个值表示4字节数目,所以最大长度2^4*4=60。

1.2.2 头部意义

UDP头部和TCP头部表示的意思不同,UDP头部是整个数据报的长度,因为UDP头部固定8个字节,所以不用标识多长。
更多TCP信息请查看
TCP三次握手,四次挥手,通俗易懂!!!
Linux C语言TCP协议实战

1.2.3 头部参数

源端口号:这个可有可无,数据报是无连接的,只需给数据报指定发送方就行了(sendto函数后面会介绍)。由于不需要消耗额外的资源消耗在连接、同步、拥塞控制、流量控制等等机制上,这也是UDP传输快速的原因。
目的端口号:数据报的的接收端必须指定,网络层和链路层通过路由、链路等方法,将数据迅速的发送到指定端口。
UDP长度:指定了数据报的长度,UDP头部固定长度无需指定。
校验和:确认数据是否错误。

1.3 UDP数据长度控制

下面这两张图的意思是设置了IP_MTU_DESCOVER套接字选项,发送数据端会追踪目标IP的最大传输单元(MTU)的大小,而不是SOCK_STREAM数据形式的(也就是不是TCP协议)传输协议会默认使用MTU追踪,默认选项可以在/proc/sys/net/ipv4/ip_no_pmtu_disc文件下设置,从最后一张图中默认为0,默认使用IP_PMTUDISC_WANT选项,这个选项会根据追踪到的目的端MTU的大小来控制数据报的尺寸,关闭这个选项数据超过MTU(加协议头部)UDP会进行数据分片,但是不建议关闭,这样会影响到UDP数据的发送速度,这些是IP层的知识,不多讲,我也懂的不多。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.4 UDP协议建立框架

UDP协议没有一对一建立连接,只需要确定服务器的IP和端口就可以了,所以不用多线程和和多进程进行处理。
在这里插入图片描述

2. 函数介绍

2.1 sendto函数

向指定端口发送数据,在函数中,出现sockaddr结构体,发送端可以不用绑定端口,直接发送数据。

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr*dest_addr, socklen_t addrlen);
/*
sockfd: socket函数返回的文件描述符
buf:  数据
len: 数据长度
flags: 可选参数一般填0,更多选项可在man sendto中查看
dest_addr:  网络通用结构体
addrlen:  结构体长度
*/

2.2 recvform函数

阻塞等待接收数据,接收端可以不用绑定端口直接接收数据。

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
sockfd: socket函数返回的文件描述符
buf:  数据
len: 数据长度
flags: 可选参数一般填0,更多选项可在man sendto中查看
src_addr:  网络通用结构体
addrlen:结构体长度

2.3 其他函数

关于端口和IP地址的主机字节序和网络字节序可以在这篇文章查找:TCP/IP传输协议,易懂!!!
实战代码中用到的其他网络相关函数可以在这篇文章中查找:Linux C语言TCP协议实战

3.实例

3.1 通用结构体、IPV4结构体、IPV6结构体

struct sockaddr {unsigned short sa_family;  // 地址族,用于指定地址类型,例如 AF_INET(IPv4)、AF_INET6(IPv6)等char sa_data[14];          // 地址数据,具体格式和长度取决于地址族的不同
};IPV6结构体
struct sockaddr_in6 {sa_family_t sin6_family;   /* 地址族,这里是 AF_INET6,表示 IPv6 地址 */in_port_t sin6_port;       /* 端口号,使用网络字节序 */uint32_t sin6_flowinfo;    /* IPv6 流信息 */struct in6_addr sin6_addr;  /* IPv6 地址 */uint32_t sin6_scope_id;    /* IPv6 范围 ID */
};
IPV4结构体
struct sockaddr_in {sa_family_t sin_family;   // 地址族(address family),通常是 AF_INET,表示使用 IPv4 地址in_port_t sin_port;       // 16 位的端口号,需要使用 `htons()` 函数转换为网络字节序struct in_addr sin_addr;  // 存储 IPv4 地址的结构体char sin_zero[8];         // 填充字节,为保持与 `struct sockaddr` 一致,一般设置为 0
};struct in_addr{uint32_t s_addr;}

3.2 框架搭建

3.2.1 client

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h>    //POSIX.1不需要包含,一些旧版本(BSD)需要包含
#include <sys/socket.h>    
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <unistd.h> 
#include <string.h>
#include <strings.h>int main(int argc, char const *argv[])
{int sockfd;//初始化网络结构体struct sockaddr_in XXX; ......//1.创建套接字socket()...//客户端绑定端口,客户端在sendto发送数据的时候,操作系统会随机配置一个端口给客户端,bind一般不用#if COND_COMPILLE  ...bind()	...#endifwhile(1){//2.通信...sendto()   //发送数据...recvfrom()   //阻塞接收...}//3.关闭套接字close(sockfd);return 0;
}

3.2.2 server

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h>
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <unistd.h> 
#include <string.h>int main(int argc, char const *argv[])
{int sockfd; //初始化网络结构体struct sockaddr_in XXX;......//1.创建套接字socket()...//2.绑定端口,用于接收数据bind()...char readBuf[BUF_SIZE] = {0};while(1){//3.数据处理...recvfrom()   //阻塞接收数据...sendto()     //做出响应...}//4.关闭套接字close(sockfd);return 0;
}

3.3 服务端和客户端编写

3.3.1 client_udp.c

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h>
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <unistd.h> 
#include <string.h>
#include <strings.h>#define BUF_SIZE 256
#define COND_COMPILE 0	
#define QUIT_FLAG "quit"int main(int argc, char const *argv[])
{if(argc !=3 ){printf("input para is incorrent\n");exit(1);}//1.创建套接字int sockfd;//初始化网络结构体struct sockaddr_in serveraddr; socklen_t addrlen = sizeof(serveraddr);bzero(&serveraddr, addrlen);serveraddr.sin_family = AF_INET;serveraddr.sin_addr.s_addr = inet_addr(argv[1]);serveraddr.sin_port = htons(atoi(argv[2]));if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){perror("fail to socket");exit(1);}
//客户端绑定端口,一般不用#if COND_COMPILLE  struct sockaddr_in clientaddr;clientaddr.sin_family = AF_INET;clientaddr.sin_addr.s_addr = inet_addr(argv[3]); clientaddr.sin_port = htons(atoi(argv[4])); if(bind(sockfd, (struct sockaddr *)&clientaddr, addrlen) < 0){perror("fail to bind");exit(1);}#endifchar readBuf[BUF_SIZE] = {0};char writeBuf[BUF_SIZE] = {0};while(1){//3.通信fgets(writeBuf, BUF_SIZE-1, stdin);size_t len = strlen(writeBuf);writeBuf[len-1] = '\0';if(sendto(sockfd, writeBuf, (len-1), 0, (struct sockaddr*)&serveraddr, sizeof(serveraddr))==-1){perror("sendto");exit(1);}printf("send complete\n");if(!strncasecmp(writeBuf, QUIT_FLAG, strlen(QUIT_FLAG))){printf("the client exit\n");break;}if(recvfrom(sockfd, readBuf, BUF_SIZE, 0,(struct sockaddr*)&serveraddr, &addrlen)==-1){perror("recvfrom");exit(1);}printf("%s\n",readBuf);bzero(readBuf, BUF_SIZE);bzero(writeBuf, BUF_SIZE);}//关闭套接字close(sockfd);return 0;
}

3.3.2 sever_udp.c

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h>
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <unistd.h> 
#include <string.h>#define HOST_PORT 5001
#define BUF_SIZE 256
#define QUIT_FLAG "QUIT"
#define RESP ",RESP"
int main(int argc, char const *argv[])
{int sockfd; //初始化网络结构体struct sockaddr_in serveraddr,cin;socklen_t addrlen = sizeof(cin);bzero(&serveraddr, sizeof(serveraddr));serveraddr.sin_family = AF_INET;serveraddr.sin_addr.s_addr = INADDR_ANY;serveraddr.sin_port = htons(HOST_PORT);//1.创建套接字if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){perror("fail to socket");exit(1);}//2.绑定端口,用于接收数据if(bind(sockfd, (struct sockaddr *)&serveraddr, addrlen) < 0){perror("fail to bind");exit(1);}char readBuf[BUF_SIZE] = {0};while(1){//3.数据处理if(recvfrom(sockfd, readBuf, BUF_SIZE, 0, (struct sockaddr*)&cin, &addrlen)==-1){perror("recvform");exit(0);}printf("the client port: %d, IP: %s\n", ntohs(cin.sin_port), inet_ntoa(cin.sin_addr));printf("readBuf: %s\n", readBuf);if(!strncasecmp(readBuf, QUIT_FLAG, strlen(QUIT_FLAG))){printf("the client exit\n");break;}strncat(readBuf, RESP, strlen(RESP));if(sendto(sockfd, readBuf, BUF_SIZE, 0, (struct sockaddr*)&cin, addrlen)==-1){perror("sendto");exit(1);}printf("send complete\n");}close(sockfd);return 0;
}

3.3.3 终端结果

在这里插入图片描述

4.总结

这篇文章着重在UDP实操上,概念上涉及的不是很多。
文章有错误请指出。

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

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

相关文章

转置卷积的一些理解

转置卷积 当图像输入到卷积网络中&#xff0c;最终生成的特征图的宽高会减小 在语义分割中标签和原始图像大小一致&#xff0c;若输出宽高减小&#xff0c;不利于标签比对 于是使用转置卷积将图像宽高还原 在卷积的时候&#xff0c;通常输入大于输出&#xff0c;可根据输入大小…

如何通过 Service Mesh 构建高效、安全的微服务系统

1. 引言 1.1.什么是 Service Mesh&#xff1f; Service Mesh 是一种基础架构层&#xff0c;负责处理微服务之间的通信&#xff0c;它通过在每个服务旁边部署代理&#xff08;通常称为 Sidecar&#xff09;来捕获和管理服务间的网络流量。这种方式解耦了微服务的业务逻辑和基础…

【Linux】waitpid函数 及其 非阻塞等待和阻塞等待

父进程等待子进程结束可以通过两种方式实现&#xff1a;阻塞等待和非阻塞等待。这两种方式各有优缺点&#xff0c;适用于不同的场景。 简单来说&#xff1a; 阻塞等待&#xff1a;先等你&#xff0c;我再继续 非阻塞等待&#xff1a;不等你&#xff0c;我继续做自己的事&…

使用Python实现某易云音乐歌曲下载

前言 在这篇文章中,我们将探讨如何通过Python结合JavaScript代码来逆向网易云音乐的API接口,以获取并下载指定歌曲。请注意,本文仅用于技术学习与交流目的,实际使用时请遵守相关法律法规及服务条款。 目标网站 1. 准备工作 首先,我们需要安装一些必要的库: execjs:用…

NVIDIA RTX 5080移动版GPU真身首曝!全系要用GDDR7

英伟达下一代移动版GPU的神秘面纱似乎正在揭开&#xff0c;Moore’s Law is Dead的最新视频首次曝光了疑似RTX 5080移动版GPU的工程样品照片。 这款工程样品印有N22W-ES-A1&#xff0c;与Clevo的下一代笔记本主板规格表相匹配&#xff0c;表明该芯片确实基于NVIDIA的下一代芯片…

java 提示 避免用Apache Beanutils进行属性的copy。

避免用Apache Beanutils进行属性的copy。 Inspection info: 避免用Apache Beanutils进行属性的copy。 说明&#xff1a;Apache BeanUtils性能较差&#xff0c;可以使用其他方案比如Spring BeanUtils, Cglib BeanCopier。 TestObject a new TestObject(); TestObject b new Te…

Cadence元件A属性和B属性相互覆盖

最近在使用第三方插件集成到Cadence,协助导出BOM到平台上&#xff0c;方便对BOM进行管理和修改&#xff0c;结果因为属性A和属性B不相同&#xff0c;导致导出的BOM错误。如下图&#xff1a; ​​ 本来我们需要导出Q12&#xff0c;结果给我们导出了Q13&#xff0c;或者反之&…

【Python】基础语法错误和异常

在Python中&#xff0c;语法错误和异常是两个常见的问题。下面对它们进行简要介绍。 1.语法错误 (Syntax Error) 语法错误是指代码的语法不符合Python的语言规则。当Python解释器读取程序代码时&#xff0c;如果发现语法不正确&#xff0c;就会抛出语法错误。这种错误通常在代…

SpringBoot实现的高效民宿预订平台

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

AWD的复现

学习awd的相关资料&#xff1a;速成AWD并获奖的学习方法和思考记录- Track 知识社区 - 掌控安全在线教育 - Powered by 掌控者&#xff08;包含使用脚本去批量修改密码&#xff09; 在复现之前去了解了以下AWD的相关脚本 资料&#xff1a;AWD批量攻击脚本使用教程-CSDN博客 …

cfg80211-- 修复添加EHT的capabilities能力供驱动使用

需求: 添加支持以检索信标模板中用户空间传递的EHT功能和EHT操作元素,并将指针存储在结构cfg80211_ap_settings中供驱动程序使用 在nl80211_calculate_ap_params方法种 ---------------------------- net/wireless/nl80211.c ---------------------------- index f3ad5f2.…

etcd入门到实战

概述&#xff1a;本文将介绍etcd特性、使用场景、基本原理以及Linux环境下的实战操作 入门 什么是etcd&#xff1f; etcd是一个分布式键值存储数据库 关键字解析&#xff1a; 键值存储&#xff1a;存储协议是 key—value 的形式&#xff0c;类似于redis分布式&#xff1a;…

13_渲染器的设计

目录 渲染器与响应式系统的结合渲染器的基本概念自定义渲染器 渲染器与响应式系统的结合 渲染器与响应式系统是相辅相成的&#xff0c;渲染器负责将响应式系统中的响应式数据渲染到视图中&#xff0c;而响应式系统则负责监听数据的变化并通知渲染器进行更新。 渲染器在浏览器…

大数据-184 Elasticsearch - 原理剖析 - DocValues 机制原理 压缩与禁用

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

在 Docker 中搭建 PostgreSQL16 主从同步环境

1. 环境搭建 本文介绍了如何在同一台机器上使用 Docker 容器搭建 PostgreSQL 的主从同步环境。通过创建互联网络和配置主库及从库&#xff0c;详细讲解了数据库初始化、角色创建、数据同步和验证步骤。主要步骤包括设置主库的连接信息、创建用于复制的角色、使用 pg_basebacku…

2024系统分析师考试---论区块链技术及其应用

试题三论区块链技术及其应用 区块链作为一种分布式记账技术,目前已经被应用到了资产管理、物联网、医疗管理、政务监管等多个领域,从网络层面来讲,区块链是一个对等网络(Peer to Peer,P2P),网络中的节点地位对等,每个节点都保存完整的账本数据,系统的运行不依赖中心化节…

成都跃享未来教育咨询有限公司抖音小店新生态

在数字化浪潮席卷全球的今天&#xff0c;教育行业正经历着前所未有的变革与升级。作为一座历史悠久而又充满活力的城市&#xff0c;成都凭借其深厚的文化底蕴和前瞻性的发展眼光&#xff0c;孕育了众多创新型企业。其中&#xff0c;成都跃享未来教育咨询有限公司&#xff08;以…

计算机专业大学四年的学习路线(非常详细),零基础入门到精通,看这一篇就够了

前言 许多学子选择踏上计算机这条充满挑战与机遇的道路。但在大学四年中&#xff0c;如何规划自己的学习路线&#xff0c;才能在毕业时脱颖而出&#xff0c;成为行业的佼佼者呢&#xff1f; 第一学年&#xff1a;基础知识的奠基 1.1 课程安排 在大学的第一年&#xff0c;重…

YoloV10改进:Block改进|使用ContextAggregation模块改善C2f模块|即插即用

摘要 在计算机视觉领域,目标检测与实例分割任务一直是研究的热点。YoloV10作为目标检测领域的佼佼者,凭借其出色的性能和效率赢得了广泛的认可。然而,随着技术的不断进步,如何进一步提升YoloV10的性能成为了我们追求的目标。近期,我们引入了ContextAggregation模块对Yolo…

spark:Structured Streaming介绍

文章目录 1. Structured Streaming介绍1.1 实时计算和离线计算1.1.1 实时计算1.1.2 离线计算 1.2 有界和无界数据 2. 简单使用3. 编程模型4. 数据处理流程4.1 读取数据Source4.1.1 文件数据处理 4.2 计算操作 Operation4.3 数据输出 Sink4.3.1 输出模式4.3.2 指定输出位置4.3.3…