TCP中异常关闭链接的意义 异常关闭的情况
终止一个连接的正常方式是发送FIN。 在发送缓冲区中 所有排队数据都已发送之后才发送FIN,正常情况下没有任何数据丢失。
但我们有时也有可能发送一个RST报文段而不是F IN来中途关闭一个连接。这称为异常关闭 。
进程关闭socket的默认方式是正常关闭,如果需要异常关闭,利用 SO_LINGER选项来控制。
异常关闭一个连接对应用程序来说有两个优点:
(1)丢弃任何待发的已经无意义的 数据,并立即发送RST报文段;
(2)RST的接收方利用关闭方式来 区分另一端执行的是异常关闭还是正常关闭。
值得注意的是RST报文段不会导致另一端产生任何响应,另一端根本不进行确认。收到RST的一方将终止该连接。程序行为如下:
阻塞模型下,内核无法主动通知应用层出错,只有应用层主动调用read()或者write()这样的IO系统调用时,内核才会利用出错来通知应用层对端RST。
非阻塞模型下,select或者epoll会返回sockfd可读,应用层对其进行读取时,read()会报错RST。
游戏测试过程中发现某些socket错误经常出现,以下是测试游戏服务器时通常考虑的case.
服务器端:
1.
Case:客户端程序正常运行的情况下,拔掉网线,杀掉客户端程序
目的:模拟客户端死机、系统突然重启、网线松动或网络不通等情况
结论:这种情况下服务器程序没有检测到任何异常,并最后等待“超时”才断开TCP连接
2.
Case:客户端程序发送很多数据包后正常关闭Socket并exit进程(或不退出进程)
目的:模拟客户端发送完消息后正常退出的情况
结论:这种情况下服务器程序能够成功接收完所有消息,并最后收到“对端关闭”(Recv返回零)消息
3.
Case:客户端程序发送很多数据包后不关闭Socket直接exit进程
目的:模拟客户端程序退出而忘记关闭Socket的情况(比如通过Windows窗口的关闭图标退出进程,而没有捕获相应关闭事件做正常退出处理等)
结论:这种情况下服务器程序能够收到部分TCP消息,然后收到“104: Connection reset by peer”(Linux下)或“10054: An existing connection was forcibly closed by the remote host”(Windows下)错误
4.
Case:客户端程序发送很多数据包的过程中直接Kill进程
目的:模拟客户端程序崩溃或非正常方式结束进程(比如Linux下”kill -9″或Windows的任务管理器杀死进程)的情况
结论:这种情况下服务器程序很快收到“104: Connection reset by peer”(Linux下)或“10054: An existing connection was forcibly closed by the remote host”(Windows下)错误
5.
Case:客户端程序发送很多数据包后正常关闭Socket并exit进程(或不退出进程)
目的:模拟客户端正常关闭Socket后,服务器端在检查到TCP对端关闭前向客户端发送消息的情况
结论:这种情况下服务器程序接收和发送部分TCP消息后,在Send消息时产生“32: Broken pipe”(Linux下)或“10053: An established connection was aborted by the software in your host machine”(Windows下)错误
总结:
当TCP连接的进程在忘记关闭Socket而退出、程序崩溃、或非正常方式结束进程的情况下(Windows客户端),会导致TCP连接的对端进程产生“104: Connection reset by peer”(Linux下)或“10054: An existing connection was forcibly closed by the remote host”(Windows下)错误
当TCP连接的进程机器发生死机、系统突然重启、网线松动或网络不通等情况下,连接的对端进程可能检测不到任何异常,并最后等待“超时”才断开TCP连接
当TCP连接的进程正常关闭Socket时,对端进程在检查到TCP关闭事件之前仍然向TCP发送消息,则在Send消息时会产生“32: Broken pipe”(Linux下)或“10053: An established connection was aborted by the software in your host machine”(Windows下)错误
客户端
1.
服务器端已经close了Socket,客户端再发送数据
目的:测试在TCP对端进程已经关闭Socket时,本端进程还未检测到连接关闭的情况下继续向对端发送消息
结论:第一包可以发送成功,但第二包发送失败,错误码为“10053: An established connection was aborted by the software in your host machine”(Windows下)或“32: Broken pipe,同时收到SIGPIPE信号”(Linux下)错误
2.
服务器端发送数据到TCP后close了Socket,客户端再发送一包数据,然后接收消息
目的:测试在TCP对端进程发送数据后关闭Socket,本端进程还未检测到连接关闭的情况下发送一包消息,并接着接收消息
结论:客户端能够成功发送第一包数据(这会导致服务器端发送一个RST包 <已抓包验证>),客户端再去Recv时,对于Windows和Linux程序有如下不同的表现:
Windows客户端程序:Recv失败,错误码为“10053: An established connection was aborted by the software in your host machine”
Linux客户端程序:能正常接收完所有消息包,最后收到正常的对端关闭消息(这一点与Window下不一样)
3.
服务器端在TCP的接收缓冲区中还有未接收数据的情况下close了Socket,客户端再收包
目的:测试在TCP的接收缓冲区中还有未接收数据的情况下关闭Socket时,对端进程是否正常
结论:这种情况服务器端就会向对端发送RST包,而不是正常的FIN包(已经抓包证明),这就会导致客户端提前(RST包比正常数据包先被收到)收到“10054: An existing connection was forcibly closed by the remote host”(Windows下)或“104: Connection reset by peer”(Linux下)错误
总结:
当TCP连接的对端进程已经关闭了Socket的情况下,本端进程再发送数据时,第一包可以发送成功(但会导致对端发送一个RST包过来):
之后如果再继续发送数据会失败,错误码为“10053: An established connection was aborted by the software in your host machine”(Windows下)或“32: Broken pipe,同时收到SIGPIPE信号”(Linux下)错误;
之后如果接收数据,则Windows下会报10053的错误,而Linux下则收到正常关闭消息
TCP连接的本端接收缓冲区中还有未接收数据的情况下close了Socket,则本端TCP会向对端发送RST包,而不是正常的FIN包,这就会导致对端进程提前(RST包比正常数据包先被收到)收到“10054: An existing connection was forcibly closed by the remote host”(Windows下)或“104: Connection reset by peer”(Linux下)错误
TCP中异常关闭链接的意义 异常关闭的情况的更多相关文章
- java在线聊天项目1.0版 异常处理——开启多个客户端,关闭一个客户端后,在其他客户端中再发出信息会出现异常的处理
异常一 只开启一个客户端,输入信息后关闭,客户端出现如下异常 根据异常说明 ChatClientFrame客户端117行 提示原因是Socket关闭 分析原因 客户端代码 while (connect ...
- 业务系统中最核心的状态设计,异常 case. (系统设计)
系统设计几方面 1. 具象: 几个角色 -- 用例 2. 具象: 边界模块 3. 具象: 实体模块 4. 抽象: 详细设计后,抽出公用的部分. 5. Status状态字段的设置和更改 系统设计中最核心 ...
- JedisPool异常Jedis链接处理
问题现象(jedis-2.1.0.jar) 基于JedisPool管理Jedis对象,通过get方法获取值,出现key对应的value值错误,例如: K V a a b b Jedis.get(“a” ...
- C# Webservice 解决在运行配置文件中指定的扩展时出现异常。 ---> System.Web.HttpException: 超过了最大请求长度问
摘自: http://blog.csdn.net/gulijiang2008/article/details/4482993 请在服务器端配置 方法一: 在通过WebService处理大数据量数据时出 ...
- AsyncHttpClient 中的重定向和 setEnableRedirects 方法异常解决
今天使用 AsyncHttpClient 开源库,遇到个很崩溃的问题: 方法 setEnableRedirects(false); 从名称上看应该是重定向开关的方法,设置为 false 后则普通请 ...
- 更优雅地关闭资源 - try-with-resource及其异常抑制
原文:https://www.cnblogs.com/itZhy/p/7636615.html 一.背景 我们知道,在Java编程过程中,如果打开了外部资源(文件.数据库连接.网络连接等),我们必须在 ...
- Java进阶知识点3:更优雅地关闭资源 - try-with-resource及其异常抑制
一.背景 我们知道,在Java编程过程中,如果打开了外部资源(文件.数据库连接.网络连接等),我们必须在这些外部资源使用完毕后,手动关闭它们.因为外部资源不由JVM管理,无法享用JVM的垃圾回收机制, ...
- 更优雅地关闭资源 - try-with-resource及其异常抑制--转载
原文地址:https://www.cnblogs.com/itZhy/p/7636615.html 一.背景 我们知道,在Java编程过程中,如果打开了外部资源(文件.数据库连接.网络连接等),我们必 ...
- 在Global.asax中 注册Application_Error事件 捕获全局异常
参考于:https://shiyousan.com/post/635813858052755170 在ASP.NET MVC中,通过应用程序生命周期中的Application_Error事件可以捕获到 ...
随机推荐
- 3801. String LD
Description Stringld (left delete) is a function that gets a string and deletes its leftmost charact ...
- git的几种回滚 git revert 和 git reset的区别
git的几种回滚 git revert 和 git reset的区别:强烈建议:对HEAD不熟的话最好不要用HEAD,直接用commitID吧,我遇到的问题:reset HEAD~1之后,可能是别人提 ...
- BZOJ4553: [Tjoi2016&Heoi2016]序列
Description 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值 可能会变化,但同一个时刻最多只有一个值发生变化.现在佳媛姐姐已经研究出了所 ...
- Windows 下安装使用docker swarm machine docker toolbox
下载docker 集成安装环境 http://get.daocloud.io/#install-toolbox 这个网站很不错,下载 这个集成了 docker docker-machine ,还有gi ...
- python 之Twsited
Twisted是一个事件驱动的网络框架,其中包含了诸多功能,例如网络协议,线程,数据库管理,网络操作,电子邮件等 事件驱动 一,注册事件 二,触发事件 自定义事件框架 event_fram.py # ...
- 将bootstrap弹出框的点击弹出改为鼠标移入弹出
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 读取文件内容fopen,fgets,fclose
<?php //首先采用“fopen”函数打开文件,得到返回值的就是资源类型.$file_handle = fopen("/data/webroot/resource/php/f.tx ...
- Spring注解详解
概述 注释配置相对于 XML 配置具有很多的优势: 它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作.如使用 JPA 注释配置 ORM 映射时,我们就不需要指定 PO ...
- 2_STL容器
STL算法的精髓在于 算法的 返回值!!! String: string是STL的字符串类型,通常用来表示字符串:C语言中一般用char* char*字符指针;string是类封装了char*,管 ...
- javascript 百度地图
官方地址 http://lbsyun.baidu.com/index.php?title=jspopular 示例地址 http://developer.baidu.com/map/jsdemo.ht ...