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

时间:2015-01-25 21:32:08

标签: go ports

这与必须以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    

1 个答案:

答案 0 :(得分:0)

我可以重现那个错误。 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