网络编程的一些坑

Tcp Udp发送包的大小限制问题

以太网(Ethernet)数据帧的长度必须在46-1500字节之间,这是由以太网的物理特性决定的.  
  这个1500字节被称为链路层的MTU(最大传输单元).  
  但这并不是指链路层的长度被限制在1500字节,其实这这个MTU指的是链路层的数据区.  
  并不包括链路层的首部和尾部的18个字节.

因为IP数据报的首部为20字节,所以IP数据报的数据区长度最大为1480字节. 

又因为UDP数据报的首部8字节,所以UDP数据报的数据区最大长度为1472字节. 

鉴于Internet上的标准MTU值为576字节,所以我建议在进行Internet的UDP编程时. 

 

 

tcp每次发送的包大小  最大为65535个字节,

udp给本机发送数据,单包的大小最大为4000个字节,

udp给其他主机发送数据,单包的大小最大为1500字节,

超过udp可能丢包,或者发不出去

#define MAX_TCP_SIZE 65536
#define IP_MTU_SIZE 1500
#define MAX_UDP_SIZE 4096
#define MIN_UDP_SIZE 576

UDP包最小长度限制的问题

以前知道UDP包最大不能超过65535个字节,这是因为UDP包头中的长度用了两个字节来表示。但最近发现,过小的UDP包也发不出去。

最近在公司写了个基于UDP协议的日志收集服务,逻辑很简单,客户端(PHP应用)通过socket把数据发过来,服务端记录日志并返回成功。由于开发测试时Server和Client都是同一台机器上,一直平安无事。后来又找了台机器想做一下压力,却发现无论如何Client都不到回包。通过tcpdump看,Server端的确已经回包了,但Client机器上只能看到一个发包。

这个问题排查了整个下午,因为一直没有头绪。最初想到的是网络原因,可能端口被防火墙拦截,但用nc试验收发包,没有问题,所以排除了网络原因。然后怀疑是不是某些系统调用出问题了?写了一段最简单的udp收发包代码,发现也没有问题。然后怀疑是不是框架出问题了,打了一些点,重新编译,也没有发现异常,这时想到之前用同一个框架写的服务,找出来编译运行,发现竟然可以正常收发包。然后我开始修改这个服务的发包部分,逐渐减少sendto的内容,直到不行,这时开始怀疑是不是UDP包有最小长度限制。

Google了一下,果然有人遇到类似问题。
http://bbs.csdn.net/topics/390729121
http://bbs.csdn.net/topics/60272470

继续查,发现802.3规定,以太网帧的数据部分是46~1500字节,如下图。而IP包头部占了20个字节,UDP包头部占了8个字节,还有18个字节需要填满。但测试发现,当数据部分(不含IP包头与UDP包头)小于12个字节时,会发送失败;当数据库部分大于等于12个字节而小于18个字节时,会自动被0补齐18个字节,并发送成功

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值