为什么在指定本地端口时客户端会挂起?
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)
}
}
这与必须在 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)
}
}