zoukankan      html  css  js  c++  java
  • 【理解】 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包给对方

  • 相关阅读:
    设计模式——原型链模式之在原型上设置属性
    设计模式——原型链模式
    设计模式——构造函数模式
    设计模式——工厂模式
    设计模式——单例模式
    为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?(转载)
    Unity3d中设置UISprite图片灰显方法
    游戏后端主程工作内容及游戏项目中的注意事项及游戏项目中注意事项<转载>
    xcode使用
    ios学习笔记2
  • 原文地址:https://www.cnblogs.com/pengyusong/p/6433516.html
Copyright © 2011-2022 走看看