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

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 关于#python#的问题:求帮写python代码
    • ¥15 LiBeAs的带隙等于0.997eV,计算阴离子的N和P
    • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
    • ¥15 来真人,不要ai!matlab有关常微分方程的问题求解决,
    • ¥15 perl MISA分析p3_in脚本出错
    • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
    • ¥15 ubuntu虚拟机打包apk错误
    • ¥199 rust编程架构设计的方案 有偿
    • ¥15 回答4f系统的像差计算
    • ¥15 java如何提取出pdf里的文字?