以一个简单的echo服务器为例,客户端从标准输入读入字符,发送给服务器,服务器收到后再原样返回,客户端收到后打印到标准输出。

那么,关于套接字的关闭有以下几种情形:

1,客户端关闭连接:

1.1,客户端调用close()

1.2,客户端进程关闭

1.3,客户端调用shutdown()

1.4,客户端调用close()+SO_LINGER选项

1.5,客户端崩溃

2,服务器关闭连接:

2.1,服务器调用close()

2.2,服务器进程关闭

2.3,服务器崩溃

2.4,服务器崩溃+SO_KEEPALIVE选项


1.1与1.2等价,就算客户端进程关闭,系统内核也会自动close(socket),且注意,当socket引用为0时才会真正调用close(),close()总是立即返回的,然后由系统尝试发送完内核缓冲区内的所有数据,接着才发送FIN。

说道这里,不得不谈谈TCP连接关闭的四次握手。可以看成是2组FIN, ACK。主动关闭的一方先发送FIN,收到ACK后,进入FIN_WAIT2状态,此时也叫做“半关闭”状态,特别须要注意的是,此时客户端套接字依然可以接收数据包,但是不能发送数据包。 被动关闭的一方,此时收到FIN了,一般情况下都是由于read(socket)返回0,然后得知对方关闭,close(socket)后,另外一组FIN,ACK随之产生,此时主动方进入TIME_WAIT状态。即四次握手完成。

以上即是正常情况下连接关闭的情形。

再看看1.3,shutdown()与close()主要有3点区别:

shutdown()不理会引用计数与内核缓冲区内剩余待发数据包,直接发送FIN;

shutdown()可以只关闭套接字某个方向的连接,例如关闭发送,关闭接收,或者2者都关闭;

实际上shutdown(write)后,就是上面说的半关闭情形,依然可以完成四次握手。

再看看1.4,为什么要设置SO_LINGER呢

SO_LINGER的目的就是改变close()的默认行为,可以决定close()在哪个状态返回,或者让套接字立即发送RST,从而没有FIN的发送。接收方返回ECONNRESET错误,连接直接关闭。

再来总结下1.1-1.4,这么多关闭连接的方式,那么什么方式才是最好的呢?

择优选择的方式当然是考虑最恶劣的情况,对方主机崩溃或网络故障导致数据包传输停滞。

RST不用考虑了,直接TIME_WAIT状态都没,如果有网络故障,可能下次创建的套接字还会接收到已经被销毁的套接字的数据报。

close()不能保证对方一定收到FIN。

close()+SO_LINGER虽然能控制close()在收到ACK后返回,依然不能保证四次握手完成。

shutdown()先进入半关闭状态,再调用read(),返回0(收到对方FIN)则说明四次握手正常进行,此为最优方式。

其实仔细想想,一般情况也不用这么麻烦,拿网游服务器来说,客户端close()后,就算服务器不知道,那么这种情况归为1.5讨论;如果是服务端close()而客户端不知道,那么归为2.3讨论。总之都有解决办法。。

现在再讨论1.5,很简单,服务端加入链路异常检测机制即可,这也是所有大型TCP服务器必备的机制,定时发送小数据包检测客户端是否有异常退出。


服务器关闭连接方面:

2.1,2.2等价,一般情况下也与1.1,1.2等价,只是主动关闭方是服务器了。

但是,在我们讨论的例子里,客户端要从标准输入读字符,这是阻塞方式,服务端关闭连接后,客户端无法知道,因为它阻塞在标准输入了,当我们再次输入字符,并发送,收到FIN或RST,此时客户端才关闭。总之,客户端由于某种原因,不能及时调用read(),所以无法得知服务器关闭了连接。

2.3,服务器崩溃,客户端由于一直收不到ACK,会一直尝试发送数据,标准socket大概是9分钟后才会返回错误。

2.3,服务器崩溃,客户端又长时间与服务器没有数据交互,此时设置SO_KEEPALIVE选项可得知。

CLOSE关闭连接的各种情况相关推荐

  1. 【博客278】TCP连接异常关闭的几种情况

    内容: 记录TCP连接异常关闭的几种情况 一.服务器进程异常终止: 服务进程提前终止了,系统进行进程善后处理:将所有打开的文件描述符关闭,这导致发送FIN给 客户端,客户端TCP响应ACK.客户端此时 ...

  2. Socket发完消息后,立即关闭连接,客户端丢失数据的问题

    使用.net编写服务器程序的时候,发现一个现象:如果服务器发完消息,立即关闭连接,客户端将无法收到服务器最后发的那条消息.个人猜想,会不会socket也有象文件流类似的缓存机制.果断利用visual ...

  3. TCP三次握手(建立连接)/四次挥手(关闭连接)

    相对于SOCKET开发者,TCP创建过程和链接折除过程是由TCP/IP协议栈自动创建的.因此开发者并不需要控制这个过程.但是对于理解TCP底层运作机制,相当有帮助. 而且对于有网络协议工程师之类笔试, ...

  4. c mysql 关闭连接池_数据库连接池关闭的时间

    上一篇说到分析关闭连接与不关闭连接的性能,到后来我发现自己得出的结论有误.经过多次测试发现关闭连接和不关闭连接耗费的时间基本一样.进哥也说了这是有连接池的原因.其实,自己以前对Ado.net了解的不深 ...

  5. 理解tcp关闭连接中的time_wait状态

    首先看一下tcp关闭连接时的四次握手过程: 1.Client向Server发送FIN包,表示Client主动要关闭连接,然后进入FIN_WAIT_1状态,等待Server返回ACK包.此后Client ...

  6. java spring 服务器关闭连接_java springboot websocket 服务 服务器主动关闭连接 导致 抛出java.io.EOFException异常...

    遇到这个问题不要慌,去查查众说纷纭.那我就在这里总结一下吧 存在此问题的有以下几种情况 1.ws连接不稳定经常断线: 答: 1)可能是客户和服务器之间的网络问题 2)可能是服务端内存不够用导致线程被异 ...

  7. java 控制 crt_secureCRT关闭连接自动关闭tomcat服务

    下午遇到一个神奇的问题: secureCRT登陆某个服务器,用shell脚本启动./catalina.shstart,打开日志tail -f catalina.out,此时手动关闭连接窗口,导致tom ...

  8. java httpclient 关闭_【Java系列007】HttpClient调用:你考虑过关闭连接、并发了吗?...

    你好!我是miniluo,今天和你分享使用HttpClient过程中,未考虑释放连接和并发导致的坑. HttpClient在项目中还是比较常见的,主要都是通过GET或POST请求第三方以获取响应结果. ...

  9. java socket 对方关闭_java Socket判断对方是否已关闭连接

    如何判断远端socket是否已经断开连接,如果断开那么需要重新连接. 1通过socket类的方法isClosed().isConnected().isInputStreamShutdown().isO ...

最新文章

  1. python中的enumerate函数用于遍历序列中的元素以及它们的下标
  2. [USACO4.2]工序安排Job Processing
  3. 【OpenCV 例程200篇】91. 高斯噪声、瑞利噪声、爱尔兰噪声
  4. [转载]golang sync.Pool
  5. sql中添加唯一索引(非主键)
  6. Netty工作笔记0062---WebSocket长连接开发
  7. HTTP 404 - 未找到文件 怎么样解决
  8. 一文解锁加密算法的秘密
  9. Python基础语法-print
  10. Redis 安装教程
  11. 关于最小二乘法快速计算公式汇总
  12. function函数
  13. 计算机电子怎么安装,教你怎样自己组装电脑
  14. “致广大而尽精微,极高明而道中庸。”
  15. Vue 腾讯防水墙验证
  16. Codeforces Round #322 A Vasya the Hipster
  17. Github上Laravel开源排行榜Star数31-60名
  18. 牛客《今日头条》笔试题
  19. Linux 配置关掉虚拟防火墙
  20. TypeScript 初学者入门学习笔记(一)

热门文章

  1. 国家发布世界级城市群规划上海“全球城市”
  2. jquery实现电商网站分类导航菜单
  3. abaqus帮助html,ABAQUS/CAE 常 问 界 面 操 作(转自SimWe仿真论坛
  4. 烤仔的朋友们 | 一文告诉你,什么是加密艺术?
  5. 学校考的计算机证怎么查询系统,软考证书查询网址是什么?怎么查询?
  6. 电商项目——商品规格管理
  7. 基于android的检测心率,基于Android系统的心率信息监测软件的研究与实现
  8. 微擎系统换服务器,微擎服务器迁移
  9. 连接策略与搜索引擎优化
  10. ::before和::after伪元素的使用及优惠券案例