最近在看 《linux多线程服务端编程:使用moduo C++网络库》一书中,看到一段话
“如果要主动关闭连接,如何保证对方已经收到全部数据?如果应用层有缓冲(这在非阻塞网络编程中是必需的,见下文),那么如何保证先发送完缓冲区中的数据,然后再断开连接?直接调用close(2)恐怕是不行的。”
摘录来自: 陈硕. “Linux多线程服务端编程:使用muduo C++网络库。”
往socket连接中write数据,其实先到write buffer之中的,如果是非堵塞IO write操作会立刻返回,此时数据可能还在write buffer中,还没来得及发送给对端
如果此时立刻执行close,内核会首先检查tcp的read buffer里有没有客户端发送过来的数据留在内核态没有被用户态进程读取,如果有则发送给客户端RST报文来关闭tcp连接 并丢弃write buffer里的数据,如果没有则等待write buffer里的数据发送完毕,然后再经过正常的4次分手报文断开连接。
所以直接关闭,对端是否能成功收到数据,分两种情况
1、如果write的时候,read buffer为空,那么write完立即close就没问题,
2、如果write的时候,read buffer不为空,那么对端会收到RST,连接被重置,write buffer数据可能被丢弃,对端可能收不到
对于http,如果只是类似推送一样的机制,只负责write的情况,那么可以write完直接close。