实地抓包分析http协议+报文分段
(2010-08-26 11:05:52) 转载 标签:
http tcp
分类: 实验室
分段 mtu it
以连接HUDBT(http://218.199.102.168)为例,wireshark的capture filter设为host 218.199.102.168
pcap文件已经传到ishare上去了 前三次是TCP握手建立连接。对于http1.1,如果是短时间(具体多短?不知道)内重新连接,那么不用重新建立tcp连接,上次建立的tcp连接还未断开。 第4个包是HTTP GET
第5个包是服务器返回的TCP ACK,是对第四个包的确认。因为http是基于TCP的应用层协议,所以服务器收到HTTP GET后要回一个ACK
第6、7、9的info都注明了“TCP segment of a reassembled PDU”,表明它们三个其实是属于同一个TCP报文的,只是因为MTU的限制(MTU是MAC帧的数据部分的长度限制,参见我的博文MAC、IP、UDP、TCP包结构分析, 一般系统
都设为了最大值1500),那么一个TCP报文实际只能携带1500-20byteIP头-20byteTCP头=1460byte的数据。如果 要发送的TCP数据超过1460,则必须分割。那么接收方如何知道这分割的几个TCP报文段实际上属于同一报文呢?主要就是根据被分割的几个报文段的 ACK是一样的。
第8个包是对第6、7个包的确认(为什么要在没法完的情况下就确认?不知道) 第10个包是HTTP OK,告诉客户端你的GET请求已经响应完了
第11个包是对HTTP OK的确认。至此一个http的GET-OK流程走完了。
顺便把搜到的检测本机和网关MTU值及修改本机MTU的方法贴出来 转自http://baike.http://www.china-audit.com//view/26974.htm
如何检测网关的MTU
在本机打开dos窗口,执行: ping -f -l 1472 192.168.0.1 其中192.168.0.1是网关IP地址,1472是数据包的长度。请注意,上面的参数是“-l”(小写的L),而不是“-1”。如果能ping通,表 示数据包不需要拆包,可以通过网关发送出去。如果出现: Packet needs to be fragmented but DF set. 表示数据包需要拆开来发送。此时,减少数据包长度,再执行上面的ping命令。从1400到1472之间多试几次,就能找到合适的数据包长度了。把数据包 长度加上数据包头28字节,就得到MTU的值。如果检测到网关的MTU值是1500,不需要修改。如果网关有防火墙ping不通,可以试试直接把MTU设 为1400。
如何修改本机的MTU
修改方法如下: Windows平台下 1、运行regedit
2、打开:
HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces
3、Interfaces下有多个子项,每个子项对应一个网卡。请按如下方法选择网卡:
A、确定本机用来连接Internet的网卡或拨号连接的IP,如192.168.0.19;
B、用鼠标点击Interfaces上的子项,查看键值列表中的IPAddress项; C、如果IPAddress的键值与A中的IP相同,即192.168.0.19,则该子项就是要找的网卡。
4、进入该子项,在右边的窗口里按鼠标右键,选择“新建”->“DWORD 值”,输入名称“MTU”,按回车。再用鼠标双击“MTU”,弹出修改窗口,填入MTU的值(一般为十进制的1480)。
填写前请先把基数设为十进制。 设置好后,需要重启机器才能生效。 Windows 7(XP、Vista未实测) 1、使用管理员权限运行cmd
2、使用netsh interface ipv4 show subinterfaces命令看看MTU以及本地连接名称。
3、使用netsh interface ipv4 set subinterface \连接名\store=persistent
(注:这里的连接名是你使用上面命令看到的MTU值对应的这个连接名,他在右边显示。)
附:1、此方法不用重启;2、如是ipv6就将上面的ipv4改成ipv6 Linux下可使用如下命令修改 需要root权限 ifconfig 网卡 MTU值 如 ifconfig eth0 mtu 1460
ETHERIF.C
//===========================================================================
// 嵌入式 TCP/IP 协议栈 MSC51 专用版 // ETHERIF.C = 以太网数据链路层 // 作 者:南开大学-李章林 // 注 释:李清林
// 日 期:2008 年3 月
// 声 明:英文注释由作者李章林添加,中文注释由■李清林添加。 // 转载时请保留上述信息。
// 成都理工学院/应用数字系/应用数字专业
//===========================================================================
#include \ #include \ #include \ #include \ #include \
//===========================================================================
/* call output to put a packet from IP layer to device. After Ip layer selected a device, it use output to send this packet. MemHead contain a packet and Netif tell dirver which netif it is. NOTE:MemHead->pStart point to pIPHead return:
TRUE: send successfuly.*/
// 作 者:南开大学-李章林 // 注 释:李清林
// 日 期:2008 年3 月
// 声 明:英文注释由作者李章林添加,中文注释由■李清林添加。 // 转载时请保留上述信息。
// 成都理工学院/应用数字系/应用数字专业
//--------------------------------------------------------------------------- // 程序名称:EtherOutput=以太网数据链路层发送子程序 // 入口参数:
// *MemHead=缓冲控制块指针 // *NetIf=网络接口设备队列指针 // DestIP=目的IP 地址 // 出口参数:
// BOOL=TRUE (发送成功) FALSE (发送失败)
//===========================================================================
BOOL EtherOutput(struct SMemHead DT_XDATA *MemHead,