TCP/IP缓冲区数据读取的3个问题(100分)

  • 主题发起人 主题发起人 ego
  • 开始时间 开始时间
E

ego

Unregistered / Unconfirmed
GUEST, unregistred user!
假设发送端发送了3个数据包,长度分别为128、64和32个字节。本地系统堆栈把这些数据聚合在一起,形成一个更大的数据包(共224个字节)。
在接收端,网络堆栈会把所有传入的数据聚集在一起。只要接收端一执行256字节缓冲区的recv调用,系统就会马上返回所有的224个字节。如果接收端只要求读取20个字节,则系统就只返回20个字节。

问题:当调用recv(s, buf, 20, 0)来读取缓冲区数据后:
1.已读取的20个字节是否仍在缓冲区中?
2.如果已读取的20个字节已被删除,那么剩下的204个字节是否仍在缓冲区中?
3.如果剩下的204个字节仍在缓冲区中,那么循环调用recv(s, buf, 20, 0)是否能够正确全部读取?
 
如果接收缓冲区大于待发数据,缓冲区会尽量填充数据,我认为调用recv会返回WSAEMSGSIZE错误
 
只有UDP/IP才会出现WSAEMSGSIZE错误,TCP/IP是不会出现的。因为TCP/IP属于流协议,它会把传入的数据缓存下来,并尽量地返回应用程序所要求的数据,即使被挂起的数据量比缓冲大。
 
1 已读取的20个字节是否仍在缓冲区中由第四个参数决定,对于该问题0应该是肯定的

2 如果1肯定那么这个也是肯定的

3 当然能够全部读取了
 
wisenow:
谢谢你回答我的问题。刚才还看了你的写作笔记,正想找你联系,结果你到自投罗网来了。呵呵,有没有联系的方式,还有许多问题想问你呢!
还有一个问题想问一下:
winsock的缓冲区默认是多大?是1460字节吗?
 
wisenow:
刚才查了一下资料,发现你说的是对的。
“ 0表示没特殊行为。MSG_PEEK表示要将可用的数据复制到所提供的接收端缓冲区内,但并不从系统缓冲区中将这些数据删除。待发字节数也将被返回。”
 
还有一个问题想问一下:
winsock的缓冲区默认是多大?是1460字节吗?
 
好象不是

用tserversocket嘛,干什么直接调socket呢?麻烦!
 
to firstrose:
有些功能TServerSocket是没办法做到的,必须用Winsock API才行。
 
呵呵,查了一下资料,总算明白了。之所以用1460字节作数据包长度,是因为以太帧最大只能是1500个字节,而IP头一般会占用20个字节(最大占用60个字节),而TCP头又会占用20个字节(最大占用60个字节),所以就剩下1460个字节了。
 
winsock的缓冲区默认值不是这么小的,这个值跟系统有关,不同的操作系统是不一样的。
好像至少都有16k,并且这个值是可以修改的。
 
呵呵,我估计也不止这么多,否则系统有得忙了。书上只说Windows平台的TCP/IP的缓存最大只能是64K,但没说默认是多少。
 
TCP和UDP包的大小和MTU有关,UDP在局域网内的最大值是1472(1500-8-20),在internet上MTU默认为576,所以UDP包的最大值为548(576-8-20)
 
不错,制约包大小的条件很多,不过只能取满足所有条件中最小的那一个。
谢谢大家的参与。
 
后退
顶部