免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: scutan
打印 上一主题 下一主题

请教关于UDP的一个问题 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2008-08-25 22:12 |只看该作者
原帖由 scutan 于 2008-8-25 20:37 发表
请教各位,就是在使用UDP进行传输的时候,UDP层会不会对发送的包进行分片?
也即是说我调用了sendto(sockfd, buf, 10000, ...)的话,从应用层到UDP层是10000字节的一个包,那么UDP层会不会对这个包进行分片,使 ...



从协议的角度看,UDP报文时一个数据报(datagram),发送时是通过一个整体交到IP层的,IP在根据路径MTU信息和数据报大小决定是否分片,并新成报文(packet)交由链路层。

从编码实现的角度看就很灵活了,只要满足发出报文小于路径MTU,具体在哪里分片无所谓

论坛徽章:
0
12 [报告]
发表于 2008-08-25 22:31 |只看该作者
代码是2.6.11

论坛徽章:
0
13 [报告]
发表于 2008-08-26 01:18 |只看该作者
原帖由 flw2 于 2008-8-25 22:30 发表
tcp/ip卷1上说的是IP分片的,但是实现可能在UDP层就分片了,为了效率的原因
我看了一下,代码很多,不知下面的有没有错

udp_sendmsg:

do_append_data:
    up->len += ulen;
    err = ip_append_data ...


先谢谢版主,我后来又看了一下这段源码,是这样理解的:

首先在UDP发送的整个流程为:

udp_sendmsg() - > ip_append_data() - > udp_push_pending_frames() - > ip_push_pending_frames() - >  ip_local_out() - > dst_output()

而在dst_output()函数中,会调用到ip_finish_output(),在ip_finish_output()函数中有下面的代码:

  1.         if (skb->len > ip_skb_dst_mtu(skb) && !skb_is_gso(skb))
  2.                 return ip_fragment(skb, ip_finish_output2);
复制代码


所以说对于UDP包来说,最后还是会像TCP包那样,在IP层与链路层交接的地方根据MTU的大小,调用ip_fragment()进行分包。


对于ip_append_data()中的分包,它有下面这个描述:
/*
*        ip_append_data() and ip_append_page() can make one large IP datagram
*        from many pieces of data. Each pieces will be holded on the socket
*        until ip_push_pending_frames() is called. Each piece can be a page
*        or non-page data.
*
*        Not only UDP, other transport protocols - e.g. raw sockets - can use
*        this interface potentially.
*
*        LATER: length must be adjusted by pad at tail, when it is required.
*/


这个函数会把数据包进行拆分,它是根据MTU的长度将数据拆分,并创建多个skb,用拆分后的数据进行填充,并最后将整个skb链加入到发送缓冲中sk_write_queue. 然后在ip_push_pending_frams中将之前所有的skb都合并在一起,最后再由IP层进行传输。
从这个函数看来,实际上在UDP层先是进行了分片,然后再进行组合,在组合完之后加上网络层的头部,最后由IP层向下传输到链路层。


晕,看来我以前的理解还是有误,在UDP层实际上还是会有分包的现象产生,只是这个分包分了之后会再合并在一起,估计是为了效率的原因。不过这个分包对于应用程序来说是没有影响的。

论坛徽章:
0
14 [报告]
发表于 2008-08-26 08:41 |只看该作者
晕,看来我以前的理解还是有误,在UDP层实际上还是会有分包的现象产生,只是这个分包分了之后会再合并在一起,估计是为了效率的原因。不过这个分包对于应用程序来说是没有影响的。


这个应该是和skbuff的设计有关系哈,主要是为了防止在IP层分片的时候再拷贝一次(发送到下层的报文位于线性空间),所以在udp调用的时候做了些处理。也正是由于这个原因,发送函数异常复杂。

不过对于GSO来说,由于并不要求同一个报文的所有数据位于相同的线性空间,因此linux对这种网卡类型就无需额外处理,流程也简单些

论坛徽章:
0
15 [报告]
发表于 2008-08-26 08:56 |只看该作者
那在什么情况下会在udp层分包呢?

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
16 [报告]
发表于 2008-08-26 09:23 |只看该作者
原帖由 scutan 于 2008-8-25 20:37 发表
请教各位,就是在使用UDP进行传输的时候,UDP层会不会对发送的包进行分片?
也即是说我调用了sendto(sockfd, buf, 10000, ...)的话,从应用层到UDP层是10000字节的一个包,那么UDP层会不会对这个包进行分片,使 ...


分片的工作好像在底层来做,你做应用程序,需要考虑这个问题吗

论坛徽章:
0
17 [报告]
发表于 2008-08-26 09:27 |只看该作者
原帖由 Godbach 于 2008-8-26 09:23 发表


分片的工作好像在底层来做,你做应用程序,需要考虑这个问题吗


我昨天开始的时候迷糊了, 我想如果我传送的数据较大, 当然也是在UDP缓存范围之内的, 那么UDP会不会将这个数据包进行分片, 安装上不同的UDP头部, 再传送到对端去. 如果这样的话, 我传送的数据就可能只会到达一半.

不过后来我想了一下, UDP应该不会这么实现, 不然也太不可靠了.

晚上又再看了一下UDP的实现, 发现虽然在UDP层会进行分包发送给IP层, 但是最后还是会将这些包合在一起, 加上唯一的UDP头传送到对端去. 感觉还是学到了点东西, 呵呵.

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
18 [报告]
发表于 2008-08-26 09:41 |只看该作者
原帖由 scutan 于 2008-8-26 09:27 发表


我昨天开始的时候迷糊了, 我想如果我传送的数据较大, 当然也是在UDP缓存范围之内的, 那么UDP会不会将这个数据包进行分片, 安装上不同的UDP头部, 再传送到对端去. 如果这样的话, 我传送的数据就可能只会到达 ...


是吧。而且对方接收端也会有相应的refrag,对数据包的分片进行重组。这个对应用程序就是不可见的.

论坛徽章:
0
19 [报告]
发表于 2008-08-26 16:13 |只看该作者
原帖由 scutan 于 2008-8-25 20:37 发表
请教各位,就是在使用UDP进行传输的时候,UDP层会不会对发送的包进行分片?
也即是说我调用了sendto(sockfd, buf, 10000, ...)的话,从应用层到UDP层是10000字节的一个包,那么UDP层会不会对这个包进行分片,使 ...



看完了所有的帖子, 首先UDP和IP才有可能谈分片的问题,TCP会根据MTU来决定MSS,不存在分片问题。

其次,求证问题看代码是一种方式,用工具也是一种方式。至少这个问题可以用tcpdump搞定。

论坛徽章:
0
20 [报告]
发表于 2008-08-26 16:16 |只看该作者
原帖由 flw2 于 2008-8-25 22:30 发表
tcp/ip卷1上说的是IP分片的,但是实现可能在UDP层就分片了,为了效率的原因
我看了一下,代码很多,不知下面的有没有错

udp_sendmsg:

do_append_data:
    up->len += ulen;
    err = ip_append_data ...



不清楚Linux的实现,但我要说的是,所谓的协议栈的层,是抽象的概念,其实某层的code很可能就是一个个函数,UDP调用IP的函数就可以了。

所以所谓分层只不过是抽象和总结而已,在内核看,可能某一层不存在独立的上下文。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP