Go 当指定本地端口时,为什么客户端挂起?

Go 当指定本地端口时,为什么客户端挂起?,go,ports,Go,Ports,这与必须用Java提交的家庭作业有关。程序按预期工作,打印服务器的内容。转到终端。为什么客户端在两次或多次连续运行后挂起30秒 延迟仅在指定客户端端口时发生(与分配相关) 如果不是因为defer conn.close()和只有在前一个客户端返回后才运行的客户端,我希望延迟是等待连接关闭的超时 // client.go package main import ( "fmt" "io" "log" "net" "os" ) func main() {

这与必须用Java提交的家庭作业有关。程序按预期工作,打印服务器的内容。转到终端。为什么客户端在两次或多次连续运行后挂起30秒

延迟仅在指定客户端端口时发生(与分配相关)

如果不是因为defer 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关闭顺序有关,请参见此-

在OSX上,您可以像这样处理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)
    }
}

请参阅

,可能是因为端口8081在连接关闭后仍处于等待状态。我已经试着运行你的程序,我没有任何问题,我可以按顺序运行。谢谢@siritinga。如果是这样的话,我不知道为什么netstat说它处于SYN_SENT状态,以及为什么没有为所有请求触发延迟,但它可能会导致某些情况。我也不知道。我的计算机(Ubuntu 14.04)没有问题,可能默认的TCP堆栈配置不同。无法在我的系统(go1.4 windows/amd64)上重现问题。
// 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)
    }
}