zoukankan      html  css  js  c++  java
  • 【转】3种TCP连接异常的情况。

    原文:http://www.bubuko.com/infodetail-3022082.html

    ----------------------------------

    本文介绍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
  • 相关阅读:
    敏捷之一:以终为始
    Rails non browser app高级篇-capistrano/daemon部署
    ios 5下设置屏幕方向为landscape
    Android敏捷开发实践(连载)
    Rails+Mongodb的一个重要技巧:如何得到last N Records?
    在macos x上 编译jzmq 3.x
    计划缓冲区
    转载程序员的十层楼
    特权账户是什么?
    如何管理公司的共享iPad?
  • 原文地址:https://www.cnblogs.com/oxspirt/p/14743299.html
Copyright © 2011-2022 走看看