客户端close以后服务端如何知道并执行close

在网络编程中,正常的TCP断开是这样的:

image

但是,四次挥手时当客户端调用close(socket套接字)主动断开以后,只是使用socket函数很难去判断客户端什么时候结束,应该什么时候在服务器去调用close。

这里有一下几种方法:

1.在muduo中,是客户端使用shutdown(sockfd, SHUT_WR)函数关闭写端连接,这样在服务端的epoll监听队列中,该文件描述符会产生EPOLLUP事件,在服务端就关闭连接,通过epoll事件的方式来告诉服务端关闭文件描述符。同时使用Socket::setKeepAlive(类似心跳包)防止客户端崩溃或者网络错误,没有能发送fin信号。

2.还有可以自定义结束协议,比如如果发送的数据中有一些特定的字符,那么服务端读到就自动关闭连接

3.还可以使用close并设置SO_LINGER选项

4.使用心跳包

在四次握手的过程中,发生这些问题,系统会如何处理:

1.如果只是客户端调用close,而服务器没有调用close,服务器这个端口就会一直处于close_wait状态,并且不会自动消除,而客户端会处于fin-wait-2状态,注意:close_wait状态不会超时消除,会一直占用资源,积累越多就会内核崩溃,fin-wait-2状态则在一些操作系统下可以自动超时关闭,这样就可以自动释放了,windows和linux都可以设置。可以查看这篇博客https://www.cnblogs.com/zhangshiwen/p/8312869.html

2.如果客户端主动close,但是服务端崩溃了,连ack也没有发出来,那么客户端就是fin-wait-1状态,这个状态会超时自动关闭的,具体可以看这篇微博。https://blog.csdn.net/dog250/article/details/81697403?utm_source=copy

3.服务器:发出FIN,客户端回复ACK,进入TIME_WAIT状态
客户端:没有close(),处于close_wait()状态, 
       接着向服务器继续发送数据,会出现什么情况?

客户端:因为对方关闭(相当于管道中对方的读端关闭写端写满缓冲区就会触发SIGPIPE信号,操作系统会强制关闭写端),客户端继续写的话,会触发SIGPIPE信号,操作系统会强制关闭客户端

shutdown和close函数的区别,可以参考这篇博客:https://blog.csdn.net/lgp88/article/details/7176509

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值