连接的维护.md
相对于连接的建立,关闭连接则复杂的多,远不是一个close()那么简单,关闭连接要优雅。
通常server和client都可以主动发Fin来关闭连接
对于client(非Keep-Alive),发送完请求后就可以shutdown()写端,然后收到server发来的应答,最后close掉连接。也可以不shutdown()写,等读完直接close。对于Keep-Alive的情况,就要看client的心情了,收到消息后可以断,也可以不断,server应该保证不主动断开。
对于server端,毫无疑问应该谨慎处理以上所有情况。具体说来:
- 出现各种关于连接的错误时,可以直接close()掉
- 短连接超时的请求,可以close(),也可以不关
- 长连接对方长时间没有请求(如果没有保活机制),可以close(),也可以不关
- client发出Fin,server会收到0字节,通常不能判断client是close了还是shutdown,这时server应当把消息发完,然后才可以close(),如果对方调用的是close,会收到RST,server能感知到,就可以立即close了
- 短连接正常结束,server可以close,也可以不close,大多数的实现是不close的(对HTTP1.1而言)
这种情况通常有两个原因:
- 对端已经关闭了连接,这时再写该fd会出错,此时应该关闭连接
- 对端只是shutdown()了写端,告诉server我已经写完了,但是还可以接收信息。server应该在写完所有的信息后再关闭连接。更优雅的做法是透明的传递这个行为,即server顺着关闭读端,然后发完数据后关闭。