这几天都在写MUD服务器玩玩儿,在做SOCKET LIB封装类时,考虑到一个问题,对于大数据的接收是交由使用库的人来写while循环还是在库中就做好,后来又想到MUD只是发些字符串之类和简单的对角,是否一定要用到大数据,然后我就想了下,在windows环境下,对于WINSOCK1.1来说,默认的缓冲区最大长度为8K而对于WINSOCK2来说,最大的缓冲区是64K,然后我就写了个简单的客户端,发了超过64K的字节,原本以为这个字节发不出去应该会产生
WSAEMSGSIZE,这个值是对于UDP的sendto而言的,我用的是TCP,就是为了测试下是不是也是这个值,但很明显,就是一个很大的值,大到什么程序?大到越过100K时也一样能正确发送出去,然后在接收部分,我也是用基于TCP的recv ,在这里,recv 只能接收到27.9K的数据,很明显,这个值不在8K到64K的空间,然后我用下面的代码取得缓冲区的大小
unsigned long maxsize = 0;
int size = sizeof(maxsize);
getsockopt(dsock.GetSock(),SOL_SOCKET,SO_MAX_MSG_SIZE,(char*)&maxsize,&size);
结果返回的值是:4294967295
想了很久我也想不明白到底是怎么一回事!想看了MSDN关于O_MAX_MSG_SIZE的描述:
Maximum outbound (send) message size is dependent on the underlying network MTU (maximum sized transmission unit) and hence cannot be known until after a socket is bound. Applications should use getsockopt to retrieve the value of SO_MAX_MSG_SIZE after the socket has been bound to a local address.
MTU:MTU是Maximum Transmission Unit的缩写。意思是网络上传送的最大数据包。
最后,我认为SO_MAX_MSG_SIZE与SO_RCVBUF, SO_SENDBUF没有什么太大关系。实际能够发送的的最大值与 网络中的MTU值有关系。
而对于UDP,发包最大也只能一次发小于64K的包,其中包中必须还要有协议头文之类的东西,也就是说实际上的数据+协议才小于64K,
我对于UDP作了如下判断:
udp包理论一般不要超过64k(实际上60k),如果数据包大于64k的话,就需要采用数据分包与接收端的重组技术。数据包越小, 掉包越小。并且前后发包需要一定延时,一般sleep(10),否则发送缓冲区会立即塞满,而后面发送的数据会丢掉。
但对于TCP如何呢?
对基于消息的UDP来说,只能限制它的数据大小,但从上面得到的值来看,TCP的发送能力绝对是UDP远远不及的。
在TCP协议中,大的数据实际上可能经过两次分割:第一次是TCP协议会把数据分段已装入一个TCP报文中,由于TCP报文将要被放入IP包中,所以每个分段<SO_MAX_MSG_SIZE; 第二次是IP包经过某物理时,如果IP包>该网络的MTU,那么IP协议会将该IP包切片;
以下这段是在网上的一个论坛上找到的描述:
unsigned long maxsize = 0;
int size = sizeof(maxsize);
getsockopt(dsock.GetSock(),SOL_SOCKET,SO_MAX_MSG_SIZE,(char*)&maxsize,&size);
结果返回的值是:4294967295
想了很久我也想不明白到底是怎么一回事!想看了MSDN关于O_MAX_MSG_SIZE的描述:
Maximum outbound (send) message size is dependent on the underlying network MTU (maximum sized transmission unit) and hence cannot be known until after a socket is bound. Applications should use getsockopt to retrieve the value of SO_MAX_MSG_SIZE after the socket has been bound to a local address.
MTU:MTU是Maximum Transmission Unit的缩写。意思是网络上传送的最大数据包。
最后,我认为SO_MAX_MSG_SIZE与SO_RCVBUF, SO_SENDBUF没有什么太大关系。实际能够发送的的最大值与 网络中的MTU值有关系。
而对于UDP,发包最大也只能一次发小于64K的包,其中包中必须还要有协议头文之类的东西,也就是说实际上的数据+协议才小于64K,
我对于UDP作了如下判断:
udp包理论一般不要超过64k(实际上60k),如果数据包大于64k的话,就需要采用数据分包与接收端的重组技术。数据包越小, 掉包越小。并且前后发包需要一定延时,一般sleep(10),否则发送缓冲区会立即塞满,而后面发送的数据会丢掉。
但对于TCP如何呢?
对基于消息的UDP来说,只能限制它的数据大小,但从上面得到的值来看,TCP的发送能力绝对是UDP远远不及的。
在TCP协议中,大的数据实际上可能经过两次分割:第一次是TCP协议会把数据分段已装入一个TCP报文中,由于TCP报文将要被放入IP包中,所以每个分段<SO_MAX_MSG_SIZE; 第二次是IP包经过某物理时,如果IP包>该网络的MTU,那么IP协议会将该IP包切片;
以下这段是在网上的一个论坛上找到的描述:
Internet, 路由器可能会将MTU设为不同的值路由器可能会将MTU设为不同的值;
PPPoE/ADSL:1492
Dial Up/Modem:576
以太网(Ethernet)数据帧的长度必须在46-1500字节之间,这是由以太网的物理特性决定的.
这 个1500字节被称为链路层的MTU(最大传输单元). 根据四层网络拓扑结构, 扣除IP层中的包装字段(IP数据报的首部为20字节),所以IP数据报的数据区长度最大为1480字节, 而这个1480字节就是用来放TCP传来的TCP报文段或UDP传来的UDP数据报的;另外考虑传输层UDP的首部占用8个字节,所以UDP数据报的数据区最大长度为1472字节.
很明显,就SO_MAX_MSG_SIZE这种,它可能更适合于UDP,对于TCP,它基本上是无能为力的.