为什么在指定本地端口时客户端会挂起?

Why does the client hang when the local port is specified?

这与必须在 Java 中提交的家庭作业有关。该程序按预期工作,将 server.go 的内容打印到终端。为什么客户端在连续运行两次或更多次后会挂起 30 秒?

延迟只有在指定客户端端口时才会出现(与赋值相关)

// server.go
package main

import (
    "log"
    "net/http"
)

func main() {
    log.Fatal(http.ListenAndServe(":8080", http.FileServer(http.Dir("."))))
}

我希望延迟是等待连接关闭的超时,如果不是延迟 conn.Close() 和客户端 运行 仅在前一个客户端返回之后。

// client.go
package main

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

func main() {
    d := net.Dialer{
        LocalAddr: &net.TCPAddr{
            Port: 8081,
        },
    }

    // Dial the server from client port 8081 to server port 8080
    conn, err := d.Dial("tcp", ":8080")
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    // Request the resource and log the response
    fmt.Fprint(conn, "GET /server.go HTTP/1.0\r\n\r\n")
    io.Copy(os.Stdout, conn)
}

延迟期间 netstat 的输出:

$ netstat -anp tcp | grep "8080\|8081"
tcp4       0      0  127.0.0.1.8081         127.0.0.1.8080         SYN_SENT   
tcp46      0      0  *.8080                 *.*                    LISTEN    

我可以重现该错误。 AFAICS 它与 TCP 关闭顺序有关,请参阅此 - http://www.tcpipguide.com/free/t_TCPConnectionTermination-4.htm

在 OS X 上你可以像这样搞乱 tcp MSL

sudo sysctl net.inet.tcp.msl=100

所以修改客户端

// client.go
package main

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

func check() {
    d := net.Dialer{
        LocalAddr: &net.TCPAddr{
            Port: 8081,
        },
    }

    // Dial the server from client port 8081 to server port 8080
    conn, err := d.Dial("tcp", ":8080")
    if err != nil {
        log.Fatal(err)
    }

    // Request the resource and log the response
    fmt.Fprint(conn, "GET /server.go HTTP/1.0\r\n\r\n")
    io.Copy(os.Stdout, conn)
    conn.Close()
}

// sudo sysctl net.inet.tcp.msl=100
func main() {

    count := 0
    for {
        fmt.Printf("Try num %d\n", count)
        count++
        check()
        time.Sleep(200 * time.Millisecond)
    }
}

https://en.wikipedia.org/wiki/Maximum_segment_lifetime