我们知道, IP包头有一个16bit的长度, 对应的二进制最大值是2^16 -1,也就是说一个IP包整个长度的最大值是2^16 - 1 字节, 如果考虑UDP通信, 那么除去IP头的20个字节, 除去UDP头的8个字节, 还剩2^16 - 1 - 20 - 8 字节。 我们来玩玩程序(本文只以客户端发数据为例)。
程序:
#include
#include
#include
#include
#include
#include
#include
#include
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("127.0.0.1");
srvAddr.sin_port = htons(8888);
int iSock = socket(AF_INET, SOCK_DGRAM, 0); // udp
char szBuf[1024 * 64 -1 - 20 - 8] = {0};
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;
}
结果:
send size is 65507, iRet is 65507, errmsg[Success]
好, 我们让send size变大1个字节, 试试:
#include
#include
#include
#include
#include
#include
#include
#include
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("127.0.0.1");
srvAddr.sin_port = htons(8888);
int iSock = socket(AF_INET, SOCK_DGRAM, 0); // udp
char szBuf[1024 * 64 - 20 - 8] = {0};
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;
}
结果:
send size is 65508, iRet is -1, errmsg[Message too long]
一切不言而喻, 无须解释。 学网络, 还是应该多玩代码, 多实践, 多抓包, 然后结合书本理解原理。