李成笔记网

专注域名、站长SEO知识分享与实战技巧

深入剖析客户端出现connect reset by peer报错相关的技术知识

关于http请求的报错:connect reset by peer,我相信大家应该都有所见过。今天我来剖析一下这个报错情况以及整理一下相关技术知识。

案例

报错原因:服务端断开连接,但是客户端还是复用之前的连接进行请求,则会报此错误。如果是http1协议和http1.1协议中出现此类报错,则是开启:Keep-Alive,http1.1则是默认开启Keep-Alive的,如果是用的http2协议的话,则报错是因为复用连接。

复现方式:由于这个报错基于tcp协议来实现比较方便,我这里就采用go来实现server端,客户端,并且复现报错。

实现server端代码

package main

import (
    "log"
    "net"
    "os"
)

func server() {
    listener, err := net.Listen("tcp", ":8090")
    if err != nil {
        log.Fatal(err)
    }

    defer listener.Close()
    conn, err := listener.Accept()
    if err != nil {
        log.Fatal("server", err)
        os.Exit(1)
    }

    log.Printf("server close start")
    conn.Close()
    log.Printf("server close end")
}

func main() {
     server()
}

实现客户端代码

package main

import (
    "errors"
    "log"
    "net"
    "syscall"
    "time"
)

func client() {
    conn, err := net.Dial("tcp", "124.221.97.119:8090")
    if err != nil {
        log.Fatal("client", err)
    }

    if _, err := conn.Write([]byte("ab")); err != nil {
        log.Printf("client: %v", err)
    }

    time.Sleep(1 * time.Second) // wait for close on the server side

    data := make([]byte, 1)
    if _, err := conn.Read(data); err != nil {
        log.Printf("client: %v", err)
        if errors.Is(err, syscall.ECONNRESET) {
            log.Print("This is connection reset by peer error")
        }
    }
}

func main() {
    client()
}

启动server端

server端在124.221.97.119(这个我买的临时的机器,大家不要对我这个进行进行攻击哦)这个机器上。

执行客户端

客户端在另外一个机器上,然后server端会断开,客户端则会报如下的错误:

2022/03/27 19:59:20 client: read tcp 10.23.165.46:24972->124.221.97.119:8090: read: connection reset by peer
2022/03/27 19:59:20 This is connection reset by peer error

tcpdump抓包结果

20:11:23.580281 IP xx.xx.xx.xx.24976 > 10.0.16.6.8090: Flags [S], seq 3946141306, win 64952, options [mss 1412,sackOK,TS val 3205380659 ecr 0,nop,wscale 7], length 0
20:11:23.580293 IP 10.0.16.6.8090 > xx.xx.xx.xx.24976: Flags [S.], seq 298221640, ack 3946141307, win 28960, options [mss 1460,sackOK,TS val 2496773398 ecr 3205380659,nop,wscale 7], length 0
20:11:23.588677 IP xx.xx.xx.xx.24976 > 10.0.16.6.8090: Flags [.], ack 1, win 508, options [nop,nop,TS val 3205380668 ecr 2496773398], length 0
20:11:23.588698 IP xx.xx.xx.xx.24976 > 10.0.16.6.8090: Flags [P.], seq 1:3, ack 1, win 508, options [nop,nop,TS val 3205380668 ecr 2496773398], length 2
20:11:23.588703 IP 10.0.16.6.8090 > xx.xx.xx.xx.24976: Flags [.], ack 3, win 227, options [nop,nop,TS val 2496773406 ecr 3205380668], length 0
20:11:23.589014 IP 10.0.16.6.8090 > xx.xx.xx.xx.24976: Flags [R.], seq 1, ack 3, win 227, options [nop,nop,TS val 2496773407 ecr 3205380668], length 0

截图如下:

好了,上面的报错我们已经给大家复现出来了,下面我们来看一下另外一种情况,假如我们直接执行上面的client代码,会得到如下的报错:

2022/03/27 20:20:06 clientdial tcp 124.221.97.119:8090: connect: connection refused
exit status 1

这个时候的关于tcpdump抓包则会出现如下信息:

20:23:52.448494 IP xx.xx.xx.xx.25010 > 10.0.16.6.8090: Flags [S], seq 2442872680, win 64952, options [mss 1412,sackOK,TS val 3206129524 ecr 0,nop,wscale 7], length 0
20:23:52.448524 IP 10.0.16.6.8090 > xx.xx.xx.xx.25010: Flags [R.], seq 0, ack 2442872681, win 0, length 0


关于connection refused的报错,tcp协议直接会返回RST包给客户端,我们看下下面的图。

关于connect reset by peer,tcp协议响应了RST包,造成客户端报错。具体如图:

关于上面的出现的问题,我们需要学习如下知识,才能让我们更好的分析问题,复现问题,解决好问题。

理解tcpdump的输出

20:23:52.448494 IP xx.xx.xx.xx.25010 > 10.0.16.6.8090: Flags [S], seq 2442872680, win 64952, options [mss 1412,sackOK,TS val 3206129524 ecr 0,nop,wscale 7], length 0

内容结构

第一列:时分秒毫秒 20:23:52.448494
第二列:网络协议 IP
第三列:发送方的ip地址+端口号,其中xx.xx.xx.xx是 ip,而25010是端口号
第四列:箭头 >, 表示数据流向
第五列:接收方的ip地址+端口号,其中 10.0.16.6是 ip,而8090是端口号
第六列:冒号
第七列:数据包内容,包括Flags 标识符,seq 号,ack 号,win 窗口,数据长度 length,其中 [P.] 表示 PUSH 标志位为 1,更多看Flag标识符讲解。

Flags 标识符

[S] : SYN(开始连接)
[P] : PSH(推送数据)
[F] : FIN (结束连接)
[R] : RST(重置连接)
[.] : 没有 Flag,由于除了 SYN 包外所有的数据包都有ACK,所以一般这个标志也可表示 ACK

OSI 七层模型与TCP/IP五层模型

关于分层的知识,如下。

HTTP协议

HTTP协议基于TCP/IP的传输流图解:

一个HTTPS请求的流程图解

tcp建立图解

总结

1:要学会从问题出发,学习相关问题的技术知识,深入剖析知识,这样更容易成长。
2:connect reset by peer的报错是因为出现RST重置连接引发的报错。

参考文献

https://gosamples.dev/connection-reset-by-peer/#:~:text=Typically%2C%20you%20can%20see%20the,connection%20to%20be%20forcibly%20closed.

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言