Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 764|回复: 0

TCP连接异常:broken pipe 和EOF

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-4-26 12:59:55 | 显示全部楼层 |阅读模式

    本文介绍3种TCP连接异常的情况。

    1.server端没有启动,client尝试连接

    ./client
    dial failed: dial tcp 127.0.0.1:8080: connect: connection refused
    

    通过tcpdump抓包,可以看到当server没有启动的时候,client向server8080端口发送数据后,client端会收到RST。

    2.client端读数据,突然异常退出或直接close连接

    2.1 准备

    server

    server等待连接,如果有client连接过来,连接建立后,会向client发送数据。

    server代码如下:

    package main
    
    import (
            "net"
            "log"
            "time"
    )
    
    
    func main() {
    
            addr := "0.0.0.0:8080"
    
            tcpAddr, err := net.ResolveTCPAddr("tcp",addr)
    
            if err != nil {
                    log.Fatalf("net.ResovleTCPAddr fail:%s", addr)
            }
    
            listener, err := net.ListenTCP("tcp", tcpAddr)
            if err != nil {
                    log.Fatalf("listen %s fail: %s", addr, err)
            } else {
    
                    log.Println("rpc listening", addr)
            }
    
    
            for {
                    conn, err := listener.Accept()
                    if err != nil {
                            log.Println("listener.Accept error:", err)
                            continue
                    }
    
                    go handleConnection(conn)
    
            }
    
    }
    
    
    func handleConnection(conn net.Conn) {
    
            defer conn.Close()
    
            var buffer []byte = []byte("You are welcome. I'm server.")
    
    
            for {
    
                    time.Sleep(3*time.Second)
                    n, err := conn.Write(buffer)
                    if err != nil {
                            log.Println("Write error:", err)
                            break
                    }
                    log.Println("send:", n)
    
            }
    
            log.Println("connetion end")
    
    }
    

    client

    client端连接server,并接收server端数据。

    client代码如下:

    package main
    
    
    import (
            "log"
            "net"
            "os"
    )
    
    func main() {
    
            conn, err := net.Dial("tcp", "127.0.0.1:8080")
            if err != nil {
                    log.Println("dial failed:", err)
                    os.Exit(1)
            }
            defer conn.Close()
    
    
            buffer := make([]byte, 512)
    
            for {
    
                    n, err := conn.Read(buffer)
                    if err != nil {
                            log.Println("Read failed:", err)
                            return
                    }
    
                    log.Println("count:", n, "msg:", string(buffer))
            }
    
    }
    

    2.2 操作步骤如下

    (1).client与server建立连接后

    (2).启动server

    (3).启动client

    (4).client异常退出

    client 进程异常退出或者close连接,都会发送FIN。

     ./client
    2019/04/13 19:45:44 count: 28 msg: You are welcome. I'm server.
    ^C
    

    19:45:44后, Ctrl + C 退出

    (5).查看server端报错

    ./server
    2019/04/13 19:45:17 rpc listening 0.0.0.0:8080
    
    
    
    2019/04/13 19:45:44 send: 28
    2019/04/13 19:45:47 send: 28
    2019/04/13 19:45:50 Write error: write tcp 127.0.0.1:8080->127.0.0.1:62785: write: broken pipe
    2019/04/13 19:45:50 connetion end
    

    client退出后,server发送了两次数据,第一次没有报错,第二次报错:

    2019/04/11 15:49:04 send: 28
    2019/04/11 15:49:07 Write error: write tcp 127.0.0.1:8080->127.0.0.1:54631: write: broken pipe
    

    通过tcpdump抓包可以发现,client退出后,server第一次发送给client,client返回给server RST。
    第二次在这个RST的连接上,server继续发送,出现broken pipe。

    3.server端写数据,突然异常退出或直接close连接

    3.1 准备

    server、client代码同上。

    3.2 操作步骤

    (1).client与server建立连接后

    (2).启动server

    (3).启动client

    (4).server异常退出

    server 进程异常退出或者close连接,都会发送FIN。

    ./server
    2019/04/11 15:58:46 rpc listening 0.0.0.0:8080
    2019/04/11 15:58:54 send: 28
    2019/04/11 15:58:57 send: 28
    ^C
    

    (5).查看client报错

    ./client
    2019/04/11 15:58:54 count: 28 msg: You are welcome. I'm server.
    2019/04/11 15:58:57 count: 28 msg: You are welcome. I'm server.
    2019/04/11 15:58:58 Read failed: EOF
    

    4.总结

    • 如果server端没有启动,client尝试连接时,会收到RST。

    • 连接建立后,如果读端或者写端关闭连接,具体分两种情况:

      • 如果读端关闭连接,写端继续写,第一次写,会收到RST,再写,报错broken pipe
      • 如果写端关闭连接,读端继续读,报错EOF
    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-18 10:21 , Processed in 0.090917 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表