在前面的文章中, 我们已经了解到, 数据链路层对上层IP包的长度是有限制的, 以典型的以太网为例, 这个限制值即为MTU(最大值是1500字节), 为此, IP层对上层网络层的数据也有限制, 这个限制值是MSS(最大值为1460字节), 至于为什么是这两个值, 我们在前面的文章已经解释过了, 故不再赘述。
我们设想一下, 如果应用层需要用UDP发送2000字节的数据, 那么加上IP头和UDP头后, 就是2028个字节了, 超过了MTU的限制, 那怎么办呢? 此时, 协议栈在IP层采用了分片的机制, 把大的应用数据拆分成若干个小的数据, 也样就有了若干个IP包, 而且会保证每个IP包不超过1500字节。用图来表示就是:
可以看到, 分成了两个IP包来发送, 且第二个IP包没有UDP数据, 没有端口信息! 这一点十分值得注意。 如果过滤端口来抓包, 肯定抓不到这个IP包。 第一个包也会有点怪异, 其中UDP头中标明的包长度包含而第二个包的应用数据长度。
事实是否真的如此呢? 我们来写程序并抓包验证:
udp服务端的程序为:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
int main()
{
struct sockaddr_in srvAddr;
bzero(&srvAddr,sizeof(srvAddr));
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
srvAddr.sin_port = htons(8765);
int srvAddrLen = sizeof(srvAddr);
int iSock = socket(AF_INET, SOCK_DGRAM, 0); // udp
bind(iSock, (struct sockaddr *)&srvAddr, sizeof(srvAddr));
while(1)
{
getchar();
char szBuf[50001] = {0};
recvfrom(iSock, szBuf, sizeof(szBuf) - 1, 0, (struct sockaddr *)&srvAddr, (socklen_t*)&srvAddrLen);
printf("msg from client [%s]\n", szBuf);
}
close(iSock);
return 0;
}
udp客户端的程序为:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
int main(int argc, char *argv[])
{
struct sockaddr_in srvAddr;
bzero(&srvAddr, sizeof(srvAddr));
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr("10.100.70.140");
srvAddr.sin_port = htons(8765);
int iSock = socket(AF_INET, SOCK_DGRAM, 0); // udp
#define N 2000
char szBuf[N] = {0};
for(unsigned int i = 0; i < N; i++) //字符数组最后一个字符不要求是‘\0’
{
szBuf[i] = 'a';
}
int iRet = sendto(iSock, szBuf, sizeof(szBuf), 0, (struct sockaddr *)&srvAddr, sizeof(srvAddr));
printf("send size is %d, iRet is %d, errmsg[%s]\n", sizeof(szBuf), iRet, strerror(errno));
close(iSock);
return 0;
}
服务端抓包结果:
00:13:57.187159 IP 10.100.70.139.46671 > 10.100.70.140.ultraseek-http: UDP, length 2000
0x0000: 4500 05dc 0510 2000 4011 ae22 0a64 468b E.......@..".dF.
0x0010: 0a64 468c b64f 223d 07d8 116e 6161 6161 .dF..O"=...naaaa
0x0020: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0030: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0040: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0050: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0060: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0070: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0080: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0090: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00a0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00b0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00c0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00d0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00e0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00f0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0100: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0110: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0120: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0130: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0140: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0150: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0160: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0170: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0180: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0190: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01a0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01b0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01c0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01d0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01e0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01f0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0200: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0210: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0220: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0230: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0240: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0250: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0260: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0270: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0280: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0290: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x02a0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x02b0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x02c0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x02d0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x02e0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x02f0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0300: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0310: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0320: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0330: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0340: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0350: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0360: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0370: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0380: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0390: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x03a0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x03b0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x03c0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x03d0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x03e0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x03f0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0400: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0410: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0420: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0430: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0440: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0450: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0460: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0470: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0480: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0490: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x04a0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x04b0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x04c0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x04d0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x04e0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x04f0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0500: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0510: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0520: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0530: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0540: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0550: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0560: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0570: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0580: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0590: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x05a0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x05b0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x05c0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x05d0: 6161 6161 6161 6161 6161 6161 0000 0000 aaaaaaaaaaaa....
0x05e0: 0000 0000 0000 0000 0000 0000 ............
00:13:57.187161 IP 10.100.70.139 > 10.100.70.140: ip-proto-17
0x0000: 4500 0224 0510 00b9 4011 d121 0a64 468b E..$....@..!.dF.
0x0010: 0a64 468c 6161 6161 6161 6161 6161 6161 .dF.aaaaaaaaaaaa
0x0020: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0030: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0040: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0050: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0060: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0070: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0080: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0090: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00a0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00b0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00c0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00d0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00e0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00f0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0100: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0110: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0120: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0130: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0140: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0150: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0160: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0170: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0180: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0190: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01a0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01b0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01c0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01d0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01e0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01f0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0200: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0210: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0220: 6161 6161 0000 0000 0000 0000 0000 0000 aaaa............
0x0230: 0000 0000 ....
从结果看, 确实分为了两个IP包来发送, 第一个IP包数据的业务数据的长度是1472个字节, 但是, 你看看, 那个length是2000字节呢。 在看第二个IP包, 果然只有IP头(有IP地址), 没有UDP头(没有端口信息)。 幸好, 我们是用过滤IP方式来抓包的, 否则, 如果过滤端口抓包, 第二个包肯定住不到。
注意: IP层的分片, 对于UDP层来说, 是透明的, 无感知的。应用层更是感觉不到, 所以, 你用socket编程, 根本不知道这个东东。
我们再看看TCP, 上面说了, MSS的最大值是1460(不同系统的MSS值可能不一样, 这个值是在三次握手过程的syn包中确定的, 当然, 实际中的业务数据仍然可以小于syn包中约定的 MSS值)
回头看一下, 上面UDP例子中的IP分片实在IP层完成的, 而TCP分段是在TCP层完成的, 如图:
可以看到, TCP层提前完成了分段, 而且, 两个TCP包中都有TCP头, 这是必然的。 所以到了IP层后, 都保留了TCP头, 当然就有了端口信息啊。 这一点与IP层次的分片是不同的。
而且我们应该看到, 因为TCP包在TCP层已经做了限制, 这就决定了, 等TCP包达到IP层的时候, IP层的数据绝对不会超过MTU, 因此, 对于TCP传输来说, IP层是没有必要分片的, 因为TCP层分段的时候, 已经考虑到了这个限制。
所以, 我们经常会说, UDP传输中, IP分片, 是受到了MTU的限制, TCP传输中, TCP分段, 是受到了MSS的限制(实际上最终还是受到了MTU的限制)
事实是否真的如此呢? 我们来写程序并抓包验证:
tcp服务端程序为:
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <malloc.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <stdarg.h>
#include <fcntl.h>
int main()
{
int sockSrv = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addrSrv;
addrSrv.sin_family = AF_INET;
addrSrv.sin_addr.s_addr = INADDR_ANY;
addrSrv.sin_port = htons(8765);
bind(sockSrv, (const struct sockaddr *)&addrSrv, sizeof(struct sockaddr_in));
listen(sockSrv, 5);
struct sockaddr_in addrClient;
int len = sizeof(struct sockaddr_in);
int sockConn = accept(sockSrv, (struct sockaddr *)&addrClient, (socklen_t*)&len);
unsigned int total = 0;
while(1)
{
char szRecvBuf[5001] = {0};
int iRet = recv(sockConn, szRecvBuf, sizeof(szRecvBuf) - 1, 0);
total += iRet;
printf("iRet is %u, total %u\n", iRet, total);
getchar();
}
close(sockConn);
close(sockSrv);
return 0;
}
tcp客户端的程序为:
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <malloc.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <stdarg.h>
#include <fcntl.h>
int main()
{
int sockClient = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addrSrv;
addrSrv.sin_addr.s_addr = inet_addr("10.100.70.140");
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(8765);
connect(sockClient, ( const struct sockaddr *)&addrSrv, sizeof(struct sockaddr_in));
#define N 2000
char szSendBuf[N] = {0};
for(unsigned int i = 0; i < N; i++) //字符数组最后一个字符不要求是‘\0’
{
szSendBuf[i] = 'a';
}
int iRet = send(sockClient, szSendBuf, sizeof(szSendBuf) , 0);
printf("send size is %d, iRet is %d\n", sizeof(szSendBuf), iRet);
getchar();
close(sockClient);
return 0;
}
我们在服务端抓包, 结果为:
19:10:51.214715 IP 10.100.70.139.44840 > 10.100.70.140.ultraseek-http: Flags [.], seq 0:1416, ack 1, win 56, options [nop,nop,TS val 1277047042 ecr 1277045798], length 1416
0x0000: 4500 05bc 41c9 4000 4006 5194 0a64 468b E...A.@.@.Q..dF.
0x0010: 0a64 468c af28 223d fe86 70c6 8488 f6fd .dF..("=..p.....
0x0020: 8010 0038 cc2e 0000 0101 080a 4c1e 3102 ...8........L.1.
0x0030: 4c1e 2c26 6161 6161 6161 6161 6161 6161 L.,&aaaaaaaaaaaa
0x0040: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0050: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0060: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0070: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0080: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0090: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00a0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00b0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00c0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00d0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00e0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00f0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0100: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0110: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0120: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0130: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0140: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0150: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0160: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0170: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0180: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0190: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01a0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01b0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01c0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01d0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01e0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01f0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0200: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0210: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0220: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0230: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0240: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0250: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0260: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0270: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0280: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0290: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x02a0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x02b0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x02c0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x02d0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x02e0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x02f0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0300: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0310: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0320: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0330: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0340: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0350: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0360: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0370: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0380: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0390: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x03a0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x03b0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x03c0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x03d0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x03e0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x03f0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0400: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0410: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0420: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0430: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0440: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0450: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0460: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0470: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0480: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0490: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x04a0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x04b0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x04c0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x04d0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x04e0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x04f0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0500: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0510: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0520: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0530: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0540: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0550: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0560: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0570: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0580: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0590: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x05a0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x05b0: 6161 6161 6161 6161 6161 6161 0000 0000 aaaaaaaaaaaa....
0x05c0: 0000 0000 0000 0000 0000 0000 ............
19:10:51.214716 IP 10.100.70.139.44840 > 10.100.70.140.ultraseek-http: Flags [P.], seq 1416:2000, ack 1, win 56, options [nop,nop,TS val 1277047042 ecr 1277045798], length 584
0x0000: 4500 027c 41ca 4000 4006 54d3 0a64 468b E..|A.@.@.T..dF.
0x0010: 0a64 468c af28 223d fe86 764e 8488 f6fd .dF..("=..vN....
0x0020: 8018 0038 081d 0000 0101 080a 4c1e 3102 ...8........L.1.
0x0030: 4c1e 2c26 6161 6161 6161 6161 6161 6161 L.,&aaaaaaaaaaaa
0x0040: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0050: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0060: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0070: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0080: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0090: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00a0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00b0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00c0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00d0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00e0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x00f0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0100: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0110: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0120: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0130: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0140: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0150: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0160: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0170: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0180: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0190: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01a0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01b0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01c0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01d0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01e0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x01f0: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0200: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0210: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0220: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0230: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0240: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0250: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0260: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
0x0270: 6161 6161 6161 6161 6161 6161 0000 0000 aaaaaaaaaaaa....
0x0280: 0000 0000 0000 0000 0000 0000 ............
可见, 确实分为了两个TCP/IP包来传输, 而且要注意到, 两个IP包, 都是有TCP头的, 甚是让人欣慰。 不过, 根据我们画图分析, 两次预期的业务数据长度应该是1460字节和540字节, 而实际抓包却分别是:1416字节和584字节。 这只是实现不同而已, 在MSS的限制下, 协议栈和系统具体进行怎样的限制, 并无错误, 无可厚非。
注意: TCP层的分段, 对于应用层来说, 是透明的, 无感知的。所以, 你用socket编程的时候, 根本感觉不到这点。
其实, 到这里, 一切应该很明白了。 最后说两个不太重要的事:
1. 网络包中有很多0000, 这个不是真正的业务数据, 跟我的tcpdump有关, 可以忽略。
2. tcp实验中, 在服务端和客户端抓包, 发现都进行了tcp分段, 这是很好理解的。 但是, 在udp实验中, 服务端抓包进行了分片, 但客户端抓包发现, 居然没有预期中的分片。 其实, 猜想一下, 这也不难理解, 应该是tcpdump抓包的时机/地点的原因, 这个应该是与tcpdump的实现有关。 待到来日, 如果查明此问题, 再来叙述。 不过, 这个问题暂时看来, 不太重要。 不影响我们对本博文内容的理解。( 后来: 通过更深入的学习, 发现可能与gso相关)
先说到这里, 该吃饭了。