关于tcp缓冲区问题

LLxz_0609 2015-02-13 11:48:41
用vs2008在win7中写了一个小程序,测试tcp中send阻塞的问题。

我用
int nSize = 0;
int x=4;
getsockopt((SOCKET)peer.get_handle(), SOL_SOCKET, SO_RCVBUF, (char *)&nSize, &x);
获取socket缓冲区大小为8K.

我在服务器端recv前面Slee(10000)也就是10秒钟,然后我在客户端中发送4*8K数据,为什么send不阻塞,发送成功。
如果循环发送每次send 8K数据,第四次就会阻塞,网上说,缓冲区满了,send就会阻塞,不知道为什么第一次发送大数据不阻塞,大神帮忙解释一下。
...全文
288 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
96掌门师兄 2015-02-27
  • 打赏
  • 举报
回复
引用 4 楼 lijunbiao2080 的回复:
[quote=引用 3 楼 wxhxj0268 的回复:] send只是将你发送缓冲区的内容送给了socket底层缓冲区,而不管你每次发的包多大,在底层它是得分帧传送,而通常帧的大小总是小于数据包,而TCP为可靠协议,如果对方未收到或数据错误在底层会被重发。这样问题就来了,当你连接发送大块数据时,底层数据未发送完成,上层的数据就全部在缓冲区中,如果你发送的量超出缓冲区的限制就出现阻塞了。 对于大块数据的传送最好使用应答方式,服务端在收完一个块后发送一个应答,再接着发送下一块就安全了。
我问的问题是,一次发送超过socket缓冲区几倍的数据,再服务端不接收数据,为什么send不阻塞?[/quote] 你确定服务器不会收数据? 你发了6倍,也许对端接收了4.5倍呢? 试试再发会不会阻塞。 可以用netstat看看缓冲区使用情况。
Sandrer 2015-02-17
  • 打赏
  • 举报
回复
你一直在说的都是应用层的东西,recv的作用是把数据从底层复制到应用层,如果是阻塞操作的话函数会一直等待到底层缓冲区有数据才返回 send的作用是先把数据复制到底层,如果是阻塞操作的话等待对方的确认包后才返回 这个确认包是不经过应用层的,是系统底层在收到数据后自动发送给对方。 你所说的send调用后立刻返回,即表示对方的底层已经确认收到数据,只是还没有把数据复制到应用层而已 缓冲区的说法有很多,有应用层设置的、有系统的、还有网卡的 如果是全双工的网卡,确认包的操作就不经过系统自动完成了,只是完成后通知系统而已
LLxz_0609 2015-02-17
  • 打赏
  • 举报
回复
引用 5 楼 xiaoxiaoyu85 的回复:
[quote=引用 4 楼 lijunbiao2080 的回复:] [quote=引用 3 楼 wxhxj0268 的回复:] send只是将你发送缓冲区的内容送给了socket底层缓冲区,而不管你每次发的包多大,在底层它是得分帧传送,而通常帧的大小总是小于数据包,而TCP为可靠协议,如果对方未收到或数据错误在底层会被重发。这样问题就来了,当你连接发送大块数据时,底层数据未发送完成,上层的数据就全部在缓冲区中,如果你发送的量超出缓冲区的限制就出现阻塞了。 对于大块数据的传送最好使用应答方式,服务端在收完一个块后发送一个应答,再接着发送下一块就安全了。
我问的问题是,一次发送超过socket缓冲区几倍的数据,再服务端不接收数据,为什么send不阻塞?[/quote] 要自己的和远程的socket缓冲区都满了才会阻塞,send才发不出去,不信你试试看。[/quote] 我一次发送超过6倍缓冲区的长度,还是不会阻塞,这时发送缓冲区和远程的接受缓存都满了吧
LLxz_0609 2015-02-17
  • 打赏
  • 举报
回复
引用 5 楼 xiaoxiaoyu85 的回复:
[quote=引用 4 楼 lijunbiao2080 的回复:] [quote=引用 3 楼 wxhxj0268 的回复:] send只是将你发送缓冲区的内容送给了socket底层缓冲区,而不管你每次发的包多大,在底层它是得分帧传送,而通常帧的大小总是小于数据包,而TCP为可靠协议,如果对方未收到或数据错误在底层会被重发。这样问题就来了,当你连接发送大块数据时,底层数据未发送完成,上层的数据就全部在缓冲区中,如果你发送的量超出缓冲区的限制就出现阻塞了。 对于大块数据的传送最好使用应答方式,服务端在收完一个块后发送一个应答,再接着发送下一块就安全了。
我问的问题是,一次发送超过socket缓冲区几倍的数据,再服务端不接收数据,为什么send不阻塞?[/quote] 要自己的和远程的socket缓冲区都满了才会阻塞,send才发不出去,不信你试试看。[/quote] 我一次发送超过6倍缓冲区的长度,还是不会阻塞,这时发送缓冲区和远程的接受缓存都满了吧
LLxz_0609 2015-02-17
  • 打赏
  • 举报
回复
我一次发送6倍缓冲区的数据都不会阻塞,这个发送缓冲区和远程的接受缓存都应该满了吧
96掌门师兄 2015-02-15
  • 打赏
  • 举报
回复
引用 4 楼 lijunbiao2080 的回复:
[quote=引用 3 楼 wxhxj0268 的回复:] send只是将你发送缓冲区的内容送给了socket底层缓冲区,而不管你每次发的包多大,在底层它是得分帧传送,而通常帧的大小总是小于数据包,而TCP为可靠协议,如果对方未收到或数据错误在底层会被重发。这样问题就来了,当你连接发送大块数据时,底层数据未发送完成,上层的数据就全部在缓冲区中,如果你发送的量超出缓冲区的限制就出现阻塞了。 对于大块数据的传送最好使用应答方式,服务端在收完一个块后发送一个应答,再接着发送下一块就安全了。
我问的问题是,一次发送超过socket缓冲区几倍的数据,再服务端不接收数据,为什么send不阻塞?[/quote] 要自己的和远程的socket缓冲区都满了才会阻塞,send才发不出去,不信你试试看。
shenyi0106 2015-02-13
  • 打赏
  • 举报
回复
你应该判断send的返回值,因为send只是将数据拷贝到发送缓冲区去
LLxz_0609 2015-02-13
  • 打赏
  • 举报
回复
引用 3 楼 wxhxj0268 的回复:
send只是将你发送缓冲区的内容送给了socket底层缓冲区,而不管你每次发的包多大,在底层它是得分帧传送,而通常帧的大小总是小于数据包,而TCP为可靠协议,如果对方未收到或数据错误在底层会被重发。这样问题就来了,当你连接发送大块数据时,底层数据未发送完成,上层的数据就全部在缓冲区中,如果你发送的量超出缓冲区的限制就出现阻塞了。 对于大块数据的传送最好使用应答方式,服务端在收完一个块后发送一个应答,再接着发送下一块就安全了。
我问的问题是,一次发送超过socket缓冲区几倍的数据,再服务端不接收数据,为什么send不阻塞?
笨笨仔 2015-02-13
  • 打赏
  • 举报
回复
send只是将你发送缓冲区的内容送给了socket底层缓冲区,而不管你每次发的包多大,在底层它是得分帧传送,而通常帧的大小总是小于数据包,而TCP为可靠协议,如果对方未收到或数据错误在底层会被重发。这样问题就来了,当你连接发送大块数据时,底层数据未发送完成,上层的数据就全部在缓冲区中,如果你发送的量超出缓冲区的限制就出现阻塞了。 对于大块数据的传送最好使用应答方式,服务端在收完一个块后发送一个应答,再接着发送下一块就安全了。
LLxz_0609 2015-02-13
  • 打赏
  • 举报
回复
引用 1 楼 shenyi0106 的回复:
你应该判断send的返回值,因为send只是将数据拷贝到发送缓冲区去
判断send的返回值了,一次发送4*8K数据,返回值32K,发送成功了。

18,357

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧