- 主题:发送数据后直接关闭连接通常是错误的做法
之前在实现我自己私有的一个网络协议时,我发现了 HTTP 协议发送完数据直接就直接关闭连接的做法可能有问题。有两种场景下容易出问题:
1. 如果 HTTP 服务器与客户端之间,还有个 proxy,那直接关闭连接,那有一定的可能性因为实现错误,数据其实还没有发送到对端。
2. 调用 send() 返回成功,并不代表数据已经发送到了对端。此时直接 close() 连接并且退出进程,那接下来的数据会交由操作系统进行发送。操作系统会不会发送成功这事难说。
所以,如果一定要确定数据已经发送到对端,最好让对端发回一个确认关闭的数据包,或者等待对端关闭连接。
也是基于这个原因,WebSocket 关闭的一般会要求接收到对端的 Close Control Frame 之外才真正关闭连接。
--
FROM 222.76.77.*
感觉混淆了协议和应用两层间的关系, 你需要的是应用层的可靠传达, 肯定要做额外的处理, 协议上的发送完数据只是表示发出去了,至于发送到哪一层了说不准
另外发送完不还要读服务器的返回信息, 为啥会直接关掉
【 在 hgoldfish 的大作中提到: 】
之前在实现我自己私有的一个网络协议时,我发现了 HTTP 协议发送完数据直接就直接关闭连接的做法可能有问题。有两种场景下容易出问题:
1. 如果 HTTP 服务器与客户端之间,还有个 proxy,那直接关闭连接,那有一定的可能性因为实现错误,数据其实还没有发送到对端。
2. 调用 send() 返回成功,并不代表数据已经发送到了对端。此时直接 close() 连接并且退出进程,那接下来的数据会交由操作系统进行发送。操作系统会不会发送成功这事难说。
所以,如果一定要确定数据已经发送到对端,最好让对端发回一个确认关闭的数据包,或者等待对端关闭连接。
也是基于这个原因,WebSocket 关闭的一般会要求接收到对端的 Close Control Frame 之外才真正关闭连接。
--
FROM 101.85.234.*
主要是传输层与应用层之间,有断层。
应用协议层需要自行解决,确认发送的数据对端已经接收到,确认接收到的数据是准确的。
【 在 pangwa 的大作中提到: 】
: 感觉混淆了协议和应用两层间的关系, 你需要的是应用层的可靠传达, 肯定要做额外的处理, 协议上的发送完数据只是表示发出去了,至于发送到哪一层了说不准
: 另外发送完不还要读服务器的返回信息, 为啥会直接关掉
: 之前在实现我自己私有的一个网络协议时,我发现了 HTTP 协议发送完数据直接就直接关闭连接的做法可能有问题。有两种场景下容易出问题:
: ...................
--
修改:hgoldfish FROM 222.76.77.*
FROM 222.76.77.*
如果是socket层,有个graceful shutdown的搞法
https://learn.microsoft.com/en-us/windows/win32/winsock/graceful-shutdown-linger-options-and-socket-closure-2
以前搞libcurl时遇到过ccproxy没有graceful shutdown,
具体是配置ccproxy端需要认证,然后先用libcurl发一个不带认证信息的http请求过去,
ccproxy会回一个Auth Required响应,然后关闭socket。
但它这个关闭不是graceful shutdown,所以有时能收到这个回应,有时收不到这个回应包。
看过ccproxy的exe,导入表里没shutdown()。
在上面一些层的话,应该属于QoS了,看这个业务需要几级的QoS,可以参考MQTT的
--
FROM 123.118.191.*
所以可靠的通讯协议都是 request-reponse模式的
【 在 hgoldfish 的大作中提到: 】
: 之前在实现我自己私有的一个网络协议时,我发现了 HTTP 协议发送完数据直接就直接关闭连接的做法可能有问题。有两种场景下容易出问题:
: 1. 如果 HTTP 服务器与客户端之间,还有个 proxy,那直接关闭连接,那有一定的可能性因为实现错误,数据其实还没有发送到对端。
: 2. 调用 send() 返回成功,并不代表数据已经发送到了对端。此时直接 close() 连接并且退出进程,那接下来的数据会交由操作系统进行发送。操作系统会不会发送成功这事难说。
: ...................
--
FROM 221.219.211.*