大漠落日

while(!dead) study++;
posts - 46, comments - 126, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

MTU和IP分片

Posted on 2011-03-04 21:07 乱78糟 阅读(7921) 评论(2)  编辑 收藏 引用 所属分类: 网络编程

本文为本人闲的蛋疼时候写的。

什么是MTU?
 

最大传输单元(Maximum Transmission Unit,MTU)是指一种通信协议的某一层上面所能通过的最大数据包大小(以字节为单位)。最大传输单元这个参数通常与通信接口有关(网络接口卡、串口等)。 

比如下图显示的常见的MTU(图截自《TCP/IP详解 卷一:协议》)

如上图所示,我们平常接触的网络对数据帧的长度都有一个限制,只是其最大值不同。链路层的这个特性就称之为MTU,最大传输单元。

数据帧超过MTU怎么办?

如果IP层有一个数据包要传,而且数据的长度比链路层的MTU大,那么IP层就会进行分片,把数据包分成托干片,让每一片都不超过MTU。注意,IP分片可以发生在原始发送端主机上,也可以发生在中间路由器上。

把一个IP数据包分片以后,只有到达目的地之后才进行重新组装。重新组装由目的端的IP层完成,它的目的就是使分片和重新组装过程对于传输层(TCP和UDP)是透明的。已经分片过的数据包仍然有可能会再次进行分片,也就是说IP分片可能发生不止一次。什么保证了这点?因为IP头部中包含的数据为分片和重新组装提供了足够的信息。

来做个测试吧,看看怎么分片的,我用ping命令,也就是利用ICMP协议来测试。以太网MTU为1500,减去IP头部20个字节,再减去ICMP 8个字节,那么我们认为不分片的上限值为1500-20-8=1472。
注意看下图的实验结果,很明显。



 MTU对网速有影响?

有没有影响,就是我这几天蛋疼的问题,看看辩论帖:

正方:合理设置MTU,提升下载速度
反方:更改MTU对网络速度的影响之测试与分析

看了网络上的帖子,迷糊了,我还是自己捣鼓吧,广域网没有可比性,局域网总行吧。好,来看我写测试代码。

  1 #include <stdio.h>
  2 #include <winsock2.h>
  3 
  4 #pragma comment(lib, "Ws2_32.lib")
  5 
  6 SOCKET sock;
  7 char *buf;
  8 int len = 1472;
  9 
 10 CRITICAL_SECTION sec;
 11 
 12 int init_sock()
 13 {
 14     WSADATA wsaData;
 15     WSAStartup(MAKEWORD(2,2), &wsaData);
 16 
 17     struct sockaddr_in serverAddr;
 18 
 19     int    reuseaddrflag = 1;
 20     int iMode = 1;
 21     int optlen = sizeof(int);
 22 
 23     sock = socket(AF_INET, SOCK_DGRAM, 0);
 24     if( sock == SOCKET_ERROR )
 25     {
 26         printf("create upd sock failed.");
 27         closesocket(sock);
 28         return -1;
 29     }
 30 
 31     serverAddr.sin_family = AF_INET;
 32     serverAddr.sin_addr.s_addr = inet_addr("192.168.3.75");
 33     serverAddr.sin_port = htons(0);
 34 
 35     if( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,(char *&reuseaddrflag, optlen) == -1)
 36     {
 37         printf("set socket reuseaddr failed");
 38         closesocket(sock);
 39         return -1;
 40     }
 41 
 42 
 43     if( bind(sock,(struct sockaddr *)&serverAddr,sizeof(serverAddr)) == SOCKET_ERROR )
 44     {
 45         printf("bind sock failed.");
 46         closesocket(sock);
 47         return -1;
 48     }
 49 
 50     if( ioctlsocket(sock, FIONBIO, (u_long FAR*&iMode) != 0 )
 51     {
 52         printf("ioctlsocket sock failed.");
 53         closesocket(sock);
 54         return -1;
 55     }
 56 
 57     InitializeCriticalSection(&sec); 
 58 
 59     return 0;
 60 }
 61 
 62 
 63 
 64 DWORD WINAPI runloop(LPVOID param)
 65 {
 66     int ret;
 67     struct sockaddr_in to;
 68 
 69     to.sin_family = AF_INET;
 70     to.sin_port = htons(161);
 71     to.sin_addr.s_addr = inet_addr("192.168.3.226");
 72 
 73     buf = (char *)malloc(len);
 74     for (int i = 0; i < len; i++)
 75     {
 76         buf[i] = 'a';
 77     }
 78 
 79     while ( 1 )
 80     {
 81         //EnterCriticalSection(&sec);
 82         ret = sendto(sock, buf, len, 0, (struct sockaddr *)&to, sizeof(to));
 83         if (ret == SOCKET_ERROR)
 84         {
 85             if (WSAGetLastError() == WSAEWOULDBLOCK)
 86             {
 87                 printf("WSAEWOULDBLOCK:\n");
 88             }
 89         }
 90         //LeaveCriticalSection(&sec);
 91     }
 92     return 0;
 93 }
 94 
 95 int main()
 96 {
 97     DWORD id;
 98 
 99     init_sock();
100 
101     //for (int i =0; i < 3; i++)
102     {
103         CreateThread(NULL, 0, runloop, NULL, NULL, &id);
104     }
105 
106     while (1) {
107         Sleep(100);
108     }
109 
110     WSACleanup();
111 
112     return 0;
113 }


代码不多,关键要调整的就是第8行的变量len,先设置成前面计算的1472吧,用任务管理器和360流量监控器统计,看下运行效果:




再来看看,把len设置为1473时候的效果:



注意,上图左侧的是1472的网络占用率,右侧是1473时候的占用率,通过这个测试,发现,嘿,看来还真有影响。

这个测试仅仅是本机的发包速度,不是实际传输速度,但是这也能从一定程度说明这个问题。


但是IP包在实际网络传输过程中,走什么线路,线路上有哪些设备,这些设备的MTU又是作何设置,我们不得而知,所以,所谓修改MTU提升下载速度从原理上来说有一定道理,但是实际操作过程中没有多大的价值和意义。

什么原因?

我认为是系统协议栈为分片浪费了不少时间,不知道你可同意?求高人解答。

Feedback

# re: MTU和IP分片[未登录]  回复  更多评论   

2011-03-06 10:25 by vincent
看了那两篇文章
第一篇文章的作者一直在拿本机的MTU与网络MTU相比,然后设定成一个合适的值,已达到尽量不浪费网络资源的目的。而事实上,网络的MTU应该是会变化的,IP包的路线不是固定的。
哪怕IP包的路线固定了。
而且他所谓的网络MTU是一条通路的MTU,自然只偏向于一条通路,对于别的通路自然不会有什么效果,甚至可能是反效果了

# re: MTU和IP分片  回复  更多评论   

2011-03-06 11:04 by 乱78糟
@vincent
你的观点我同意,我认为修改MTU能够提升网速是无稽之谈,因为IP不同路线,不同设备的MTU值都是不确定的。

我这个实验仅仅是测试本机的MTU是否影响发包速度

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理