udp是不可靠、无连接的协议,不可靠是指不能检查到数据包是否安全到达对端,但应用程序可以做保证数据包到达的机制,udp是无连接的协议说明udp的开销小、数据包传输效率高,如果传输的数据小,创建连接的开销、保证数据包可靠发送需要做的工作比数据本身还有多,那么udp是一种好的选择。udp协议头包含有四部分:

(1)、源端口:16位表示取值范围是1-65535。

(2)、目的端口:也是16位。

(3)、长度:长度是16位表示,指udp数据包的整体长度,udp数据包最小是8个字节,所以它能发送的最大负载长度是65535-8。

(4)、校验和:udp的校验和用16位表示,是检验协议头和负载数据。

1、UDP协议头数据结构

udp协议头结构体是struct udphdr,结构体元素包括:源端口、目的端口、udp报文整体长度、数据包校验和。结构体定义在include/linux/udp.h文件中。

struct udphdr {__be16    source; //源端口__be16 dest;   //目的端口__be16    len;    //数据包长度__sum16  check;  //校验和
};

2、UDP控制缓冲区

在Socket BUffer的sk_buff结构体中有一个控制缓冲区,提供给tcp/udp协议头栈中各层协议存放私有数据,udp存放私有数据的结构体是struct udp_skb_cb,定义在include/net/udp.h中

struct udp_skb_cb {union {struct inet_skb_parm   h4;                 //ipv4
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)struct inet6_skb_parm   h6;                 //ipv6
#endif} header;__u16        cscov;                          //udp校验和__u8        partial_cov;                        //udp部分校验和
};
//访问缓冲区
#define UDP_SKB_CB(__skb)   ((struct udp_skb_cb *)((__skb)->cb))

h4、h6:分别是ipv4、ipv6的选项信息。

cscov:整个udp数据包的校验和。

partial_cov:部分数据的校验和。

udp缓冲区只能通过UDP_SKB_CB宏来访问。

3、udp套接字结构体

udp套接字结构体是struct udp_sock是描述了udp协议的专业特性,struct udp_sock包含了struct inet_sock,struct inet_sock是所有AF_INET地址族域套接字专用数据结构。struct udp_sock在struct inet_sock的基础是扩展了udp数据包需要的全部管理、控制信息。

struct udp_sock {/* inet_sock has to be the first member */struct inet_sock inet;
#define udp_port_hash       inet.sk.__sk_common.skc_u16hashes[0]    //struct inet_sock的数据域
#define udp_portaddr_hash   inet.sk.__sk_common.skc_u16hashes[1]
#define udp_portaddr_node   inet.sk.__sk_common.skc_portaddr_nodeint         pending;   /* Any pending frames ? 当前是否有等待的数据包 */unsigned int   corkflag;  /* Cork is required 是否要阻塞套接字*/__u16      encap_type;    /* Is this an Encapsulation socket? 是否是封装套接字*//** Following member retains the information to create a UDP header* when the socket is uncorked.*/__u16       len;       /* total length of pending frames  等待发送数据包的长度*//** Fields specific to UDP-Lite.*/__u16       pcslen;        //轻套接字等待发送的数据包长度__u16        pcrlen;        //轻套接字等待接受的数据包长度
/* indicator bits used by pcflag: */
#define UDPLITE_BIT      0x1        /* set by udplite proto init function */
#define UDPLITE_SEND_CC  0x2        /* set via udplite setsockopt         */
#define UDPLITE_RECV_CC  0x4        /* set via udplite setsocktopt        */__u8         pcflag;        /* marks socket as UDP-Lite if > 0   轻套接字标志 */__u8        unused[3];/** For encapsulation sockets.*/int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);  //封装套接字的接受函数
};

4、udp协议和套接字层的接口

udp协议和套接字层有接口结构是struct proto,定义在net/ipv4/udp.c中,主要是管理套接字和接受发送数据包的处理函数,udp接受数据包时要确定是把数据包分配给那个套接字,以便把数据包放入套接字的接受队列中提供用户读取。udp上所有打开的套接字由udp_v4_hash函数注册到struct sock *udp_hash[UDP_TABLE_SIZE]哈希链表中,端口号就是查询哈希表的哈希值。udp和套接字层的接口struct proto udp_prot定义在net/ipv4/udp.c文件中。

struct proto udp_prot = {.name         = "UDP",.owner           = THIS_MODULE,.close           = udp_lib_close,        //关闭套接字.connect    = ip4_datagram_connect,    //初始化一个连接.disconnect    = udp_disconnect,       //断开套接字.ioctl          = udp_ioctl,.destroy       = udp_destroy_sock,.setsockopt     = udp_setsockopt,.getsockopt       = udp_getsockopt,.sendmsg      = udp_sendmsg,          //发送数据包到网络层接口.recvmsg      = udp_recvmsg,          //接受应用层数据.sendpage     = udp_sendpage,.backlog_rcv    = __udp_queue_rcv_skb,.hash        = udp_lib_hash,.unhash         = udp_lib_unhash,.rehash           = udp_v4_rehash,.get_port      = udp_v4_get_port,.memory_allocated  = &udp_memory_allocated,.sysctl_mem      = sysctl_udp_mem,.sysctl_wmem      = &sysctl_udp_wmem_min,.sysctl_rmem    = &sysctl_udp_rmem_min,.obj_size       = sizeof(struct udp_sock),.slab_flags      = SLAB_DESTROY_BY_RCU,.h.udp_table     = &udp_table,
#ifdef CONFIG_COMPAT.compat_setsockopt = compat_udp_setsockopt,.compat_getsockopt = compat_udp_getsockopt,
#endif
};

upd和套接字层的接口实现了对数据的收发、管理,在AF_INET协议族初始化的过程中完成注册,注册函数是int proto_register(struct proto *prot, int alloc_slab),初始化函数是inet_init在net/ipv4/af_inet.c文件中。

static int __init inet_init(void)
{struct sk_buff *dummy_skb;struct inet_protosw *q;struct list_head *r;int rc = -EINVAL;...//注册tcp协议实例rc = proto_register(&tcp_prot, 1);if (rc)goto out_free_reserved_ports;//注册udp协议rc = proto_register(&udp_prot, 1);if (rc)goto out_unregister_tcp_proto;...}

5、udp协议和IP层之间的接口

udp协议和IP层之间的接口由struct net_protoco结构体描述,也是定义了一系列函数指针,主要的函数是接受IP层的数据包udp_rcv和处理ICMP错误信息函数udp_err。

static const struct net_protocol udp_protocol = {.handler =    udp_rcv,            //接受IP层数据包函数.err_handler = udp_err,            //icmp错误处理函数.gso_send_check = udp4_ufo_send_check,.gso_segment = udp4_ufo_fragment,.no_policy =  1,.netns_ok =  1,
};

也是在inet_init()函数中调用inet_add_protocol注册的。

static int __init inet_init(void)
{...//注册传输层的处理函数到inet_protos全局数组中if (inet_add_protocol(&icmp_protocol, IPPROTO_ICMP) < 0)printk(KERN_CRIT "inet_init: Cannot add ICMP protocol\n");//注册udp处理函数if (inet_add_protocol(&udp_protocol, IPPROTO_UDP) < 0)printk(KERN_CRIT "inet_init: Cannot add UDP protocol\n");
...}

udp协议基本数据包结构相关推荐

  1. UDP协议抓包分析 -- wireshark

    UDP协议抓包分析 – wireshark UDP是User Datagram Protocol用户数据报协议的简称.他是OSI七层模型中一种无连接的传输层协议,提供面向事务的简单的不可靠信息传送服务 ...

  2. 【车载IoT】国标《电动汽车远程服务与管理系统技术规范》:协议数据包结构及定义(重点)

    国标<电动汽车远程服务与管理系统技术规范>解读三部曲: 系统架构及协议概述: https://blog.csdn.net/XiuHua_Wu/article/details/1135301 ...

  3. MQTT协议数据包结构

    MQTT协议数据包结构 协议就是通信双方的一个约定,即,表示第1位传输的什么.第2位传输的什么--.在MQTT协议中,一个MQTT数据包由:固定头(Fixed header). 可变头(Variabl ...

  4. 【EMQX 5.0】1.3 MQTT协议数据包结构

    1. MQTT数据包         官方文档: http://mqtt.org/documentation          MQTT数据包 由以下 三部分构成 : 固定头(Fixed header ...

  5. 数据包格式_理解MQTT协议数据包结构

    在本教程中,我们将更详细地介绍MQTT协议,以及MQTT消息或数据包的格式. 我们将研究: MQTT消息格式. MQTT消息头 消息字段和编码 控制消息编码示例 介绍 MQTT是基于二进制的协议,控制 ...

  6. TCP/UDP协议抓包-工具wireshark与tcp侦听工具

    目录 一.工具下载链接 二.实验 一.工具下载链接 链接:https://pan.baidu.com/s/1nvNdCyET-8JFn_wQXuH2sw?pwd=abcd  提取码:abcd  --来 ...

  7. 多种协议数据包的结构

    以太网首部 目地MAC地址(8字节) 源MAC地址(8字节) 类型(2字节) 1.IP头的结构 版本(4位) 头长度(4位) 服务类型(8位) 封包总长度(16位) 封包标识(16位) 标志(3位) ...

  8. java udp包_基于UDP协议的数据包收发程序(代码+报告)Java

    [实例简介] 设计要求: 1)按照UDP协议数据包发送方式实现用户端之间的通信. 2)统计包的发送和接收数,计算数据包的丢失数. 3)设计美观易用的图形界面. [实例截图] [核心代码] 基于UDP协 ...

  9. 6、linux网络编程--UDP协议编程

    一.概述: UDP 是 User Datagram Protocol 的简称, 中文名是用户数据报协议,是一个简单的面向数据报的运输层协议,在网络中用于处理数据包,是一种无连接的协议.UDP 不提供可 ...

最新文章

  1. 如何设计一个通用的权限管理系统
  2. SP10628 COT - Count on a tree (树剖+可持久化线段树)
  3. nhibernate之many-to-many的性能
  4. 多维数组的行优先和列优先, 数据描述语言
  5. 半导体重磅!英飞凌宣布100亿美元收购赛普拉斯
  6. Mac - 如何安全地还原 Mac 的默认字体
  7. flash计算机硬件,实测Flash在硬件加速下的对比
  8. 双系统如何干净删除Ubuntu
  9. macbook重装系统 选择方案_Mac如何重装系统?mac重装系统教程
  10. 花花公子推荐伤感qq日志:乖不哭,我拜你
  11. 云计算产品经理入门(一)
  12. matlab怎么画map图,用MATLAB自带的worldmap及相关函数画地图
  13. Python实现:已知化学分子的输入文件坐标(高斯计算输入文件为例),求其中任意三个原子确定的平面的法向量和单位法向量
  14. 教你用Python爬取妹子图APP
  15. 通过机器学习预测电网平均总负荷
  16. 客户网站中经常用到的英文
  17. svn发布网站(转载于badb0y)
  18. 萧县机器人_萧县共享碾米机多少钱一台?
  19. My97DatePicker时间控件
  20. Linux下安装Redis详细步骤具体教程

热门文章

  1. codeforces 1716 C Robot in a Hallway
  2. Ps 初学者教程「51」如何在产品照片中改变对象颜色?
  3. 计算机如何分区不使用第三方应用,【干货】如何不用重装系统就将硬盘重新分区?...
  4. vscode快捷键-mac
  5. 阿里云AIoT正式发布IoT安全中心和IoT Studio 3.0,进一步巩固AIoT“云网边端”基础能力
  6. 无向图输出两个节点之间的所有路径
  7. 禁止编辑注册表+ 文件劫持(映像劫持)
  8. Cannot find module ‘./index.less‘ or its corresponding type declarations
  9. ctf密码学ECC,自己给自己挖坑
  10. 七年阿里老人谈新人成长