【理解】 Error 10053和 Error 10054

1. 10053

    这个错误码的意思是:  A established connection was aborted by the software in your host machine, 一个已建立的连接所在主机的软件中止 

2. 10054

    这个错误码的意思是: Connection closed by peer, 连接已经被对方关闭

10053 出现的可能原因是:数据传输超时或者协议错误。

当主动端发起连接服务器的请求,连接成功之后发送数据请求给服务器,服务器处理时间稍长,导致客户端超时关闭,等到服务器将数据写入缓冲区后,TCP协议发现socket已经关闭,所以服务器会出现10053的错误码,这是正常的现象。

10054 出现的可能原因是:对端关闭了socket(可能是异常也可能是超时),然而本端还没有感知到,依旧写入数据(对端接收缓冲区有数据),对端发现有未处理的数据直接回复RST重置连接标记,表明对端已经关闭了socket

检测出这个错误码一般是对端发送了RST包给本端,本端接收这个包, 表示对端出现了异常:  四种情况发送RST码: 

      1. 本端连接对端未打开的端口, 对端发送RST包

      2. 请求超时

      3. 已关闭连接上收到数据: 

    主要出现在连接的关闭过程,当请求关闭连接的一方在两个MSL后,仍然收到服务机发送来的最后一个FIN,说明其最后发送出的ACK丢包, 服务机又重发了FIN包,而此时客户机已经不处于TIME_OUT状态,连接已经彻底不存在,再收到服务机发送来的FIN,就会直接回复一个RST包,让服务机直接关闭连接,抛弃 缓冲区的所有数据。

    举一个其他例子: 主动端关闭socket,发送了fin给被动端,此时主动端无法接受和发送数据了,此时如果被动端调用read会收到fin(读取0),如果被动端write给主动端,主动端会发送rst,但rst不会立即通知到被动段,只有被动端在第二次write时,数据不会发送给主动端而是发出一个SIGPIPE信号而终止被动端(可捕获忽略该信号)

      4. close连接时, 接收缓冲区还有数据

    如果close连接时,接收缓冲区还有对端发过来的数据,则回一个RST,直接丢弃接收缓冲区的内容

      5. 设置了so_linger选项但是 l_lingertime 为0, close 时会发出RST

注意到10053和10054出现的原因有重复,以下是区分他俩的一个文章:

http://www.blogjava.net/pandawang/archive/2013/11/28/406922.html

某端出现10053和10054的在于主动端(客户端)和被动端(服务器)建立连接后,服务器非正常关闭时有没有关闭socket,这个fin包是不是在rst之前被客户端收到,fin先于rst,则10053

update problem:

今天启动flask的自带server,非常简单,就是一个直接返回字符串(有sleep操作,故意的),发送一个请求给flask,这个请求会超时: 1. 在本机上发,2. 在其他主机上发; 

发现这俩种方法的结果不同,第一种会打印10053的错误信息,第二种不会;

经过microsoft message analyzer 抓包工具分析, 第一种操作,数据包是在环路接口流动,socket很快就关闭并回收了,导致server将响应返回时报错,协议栈认为是自己关闭的所以报的10053,但其实应该是10054.

因为在一个已经关闭的socket写会引起对端发送rst,连接重置,但因为是回路接口,windows的实现可能认为是自己关闭的,所以错误码才是10053。

第二种因为不再同一个机器,对端关闭不影响,数据发送还是成功的(对端回复了rst),所以没有报错。

同样的实验在linux下面运行,报的错是 error 32 broken pipe。这点和Windows不一样,如果协议栈认为是自己关闭的,在linux上的错误应该是 error 53 ECONNABORTED。

所以数据传输的错误码,在环路接口上可能与正常的理解不同,同时与系统相关。

以下附上抓包工具的结果:

下图是client和server在统一机器上的情况:其报错10053,看右侧的第二个框,其响应并没有写入完全,就报错,所以断定是socket资源已经被销毁了,但由于是在同一个机器,所以协议层认为是自己断的,报了10053

ps:环路接口每个syn,fin,ack包都重发一遍了,不知道为啥。。。。

下图是client和server不在同一机器上的情况:其未报10053, 可以看39938消息,数据是写入缓冲区成功了,发送的时候对端回了rst,参考39950。 flask自带的server可能处理了这种并没有打印连接重置的错误

ps: 

1. close 是优雅关闭过程,当socket的引用计数减少到0,开始优雅关闭流程,发送fin包,经四次握手关闭

2. shutdown 是直接破坏socket的通信,如果指定关闭WR,则发送fin包给对方

原文地址:https://www.cnblogs.com/pengyusong/p/6433516.html