Replies: 4 comments
-
这个问题归根结底是要不要完整支持 half-open connection。 按照你的想法:
那么对方一直不接收数据怎么办?这个连接是不是就关不上了? 进一步设想,对于 echo 服务来说,如果 client 一直发数据,但是从来不接收,会不会直接撑爆 server 内存?server 要怎么应对这种情况? 根据我的经验,除了 proxy 之类的特殊应用场合,half-close connection 其实很少用到,比如 Netty 4.0 才支持它。所以为了简单起见,我选择不支持“read EOF 之后继续发送数据”。 图中的链接: https://www.zhihu.com/question/48871684/answer/113135138 |
Beta Was this translation helpful? Give feedback.
-
我觉得可以设置一个超时事件,如果在规定的时间内还没发送完数据,可判定连接已断开,关闭 socket
就像 muduo 书上说的,可以在每次发送数据之前,判断当前发送缓冲区的大小,如果发送缓冲区过大,可以判断为恶意用户,直接踢掉客户端,当然这个可以由用户自己来完成,而不是库自身 |
Beta Was this translation helpful? Give feedback.
-
基本点:如果你已经收到了 EOF,那对方不可能用这条 TCP 连接给你发任何信息。 那么你如何判断“发送完数据”呢?你 send(n) 返回 n 之后,只表示数据已经进了本机操作系统的缓冲区,至于本机什么时候把数据从网卡往外发、对方什么时候能收到、是不是能完整无误地收到等等问题,你是完全无法知道的。如果你完全不在乎你发的数据对方能不能完整收到,那也许可以用 half-open connection。否则的话,应该改进你的协议设计,让双方都没有数据需要收发的时候再关闭 TCP 连接。 值得一提的是,HTTP/1.0 协议的 GET 操作比较符合“不在乎你发的数据对方能不能完整收到”这一前提,但它也没有采用 half-open connection 的设计,客户端在发送完 GET 请求之后不会立刻 shutdown 连接,而是由服务器发送完响应之后才断开连接。 |
Beta Was this translation helpful? Give feedback.
-
我以前一直想要在解决掉所有的问题,现在才发现 half-open connection 和 应用层的 ACK 不能同时存在,必须在设计应用层的协议的时候,想清楚究竟需要哪个,多谢了。 |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
当服务器接收到 EOF 时,我觉得应该考虑的当前库的发送缓冲区不为空的情况,因为接受到 EOF 时,客户端可能仅仅关闭了 socket 的写端,所以我觉得 接受的 EOF 后, 如果库的发送缓冲区不为空时,应该尝试将库的数据发送给对方。
测试如下:
以下测试了 cpp17 分支的 echo 服务器https://github.com/chenshuo/muduo/tree/cpp17/examples/simple/echo
结果:
以下为测试程序:
Beta Was this translation helpful? Give feedback.
All reactions