duanmen2189 2017-08-27 21:29
浏览 1006

golang:net.Conn:检查conn状态

I encountered a strange behavior of the conn.Read: let's presume that I have a couple of functions for testing net.Conn:

package example

import (
    "io"
    "log"
    "net"
    "os"
    "time"
)

func CheckConn(conn net.Conn) (net.Conn, error) {
    conn.SetReadDeadline(time.Now())
    var one = []byte{}
    _, err := conn.Read(one)
    if err != nil {
        log.Println("Net err: ", err)
    }
    if err == io.EOF {
        return conn, err
    }
    var zero time.Time
    conn.SetReadDeadline(zero)
    return conn, nil
}

func CheckConnWithTimeout(conn net.Conn) (net.Conn, error) {
    ch := make(chan bool, 1)
    defer func() {
        ch <- true
    }()
    go func() {
        select {
        case <-ch:
        case <-time.After(1 * time.Second):
            log.Println("It works too long")
            os.Exit(1)
        }
    }()
    return CheckConn(conn)
}

And I want to implement tests for it, lets start with this one:

package example

import (
    "io"
    "net"
    "testing"
)


func TestClosedConn(t *testing.T) {
    server, client := net.Pipe()
    client.Close()
    defer server.Close()
    _, err := CheckConn(server)
    if err != io.EOF {
        t.Errorf("Not equal:
Expected: %v
actual: %v", io.EOF, err)
    }
}

this works pretty well, we will receive io.EOF from CheckConn function, lets add one more test:

func TestClosedConnAfterWrite(t *testing.T) {
    server, client := net.Pipe()
    go func() {
        client.Write([]byte{0xb})
    }()
    client.Close()
    defer server.Close()
    _, err := CheckConn(server)
    err = nil
    if err != io.EOF {
        t.Errorf("Not equal:
Expected: %v
actual: %v", io.EOF, err)
    }
}

looks like the first test, but we wrote to the client before(?) it was closed.

And this will not pass!

conn.Read will return &errors.errorString{s:"EOF"}, instead of io.EOF, so CheckConn will return error == nil,

It looks so weird!

But let's continue the tests, now I want to check unclosed connections:

func TestActiveConn(t *testing.T) {
       server, client := net.Pipe()
       defer client.Close()
       defer server.Close()
       _, err := CheckConnWithTimeout(server)
       if err != nil {
           t.Errorf("Not equal:
Expected: %v
actual: %v", nil, err)
       }
}

I think you noticed that I use the function with a timeout just because SetReadDeadline will not work in this case(I have no idea why!)

So what is going wrong in last two test cases? Is there a normal way to test the connection? Why SetReadDeadline is not working in this case?

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 求chat4.0解答一道线性规划题,用lingo编程运行,第一问要求写出数学模型和lingo语言编程模型,第二问第三问解答就行,我的ddl要到了谁来求了
    • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
    • ¥50 树莓派安卓APK系统签名
    • ¥15 maple软件,用solve求反函数出现rootof,怎么办?
    • ¥65 汇编语言除法溢出问题
    • ¥15 Visual Studio问题
    • ¥20 求一个html代码,有偿
    • ¥100 关于使用MATLAB中copularnd函数的问题
    • ¥20 在虚拟机的pycharm上
    • ¥15 jupyterthemes 设置完毕后没有效果