套接字客户端报错:An existing connection was forcibly closed by the remote host

server.go:

package main

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

func main() {
    service := ":8888"
    tcpAddr, err := net.ResolveTCPAddr("tcp4", service)
    checkError(err)
    listener, err := net.ListenTCP("tcp", tcpAddr)
    checkError(err)
    for {
        conn, err := listener.Accept()
        if err != nil {
            continue
        }
        daytime := time.Now().String()
        conn.Write([]byte(daytime)) // don't care about return value
        conn.Close()                // we're finished with this client
    }
}
func checkError(err error) {
    if err != nil {
        fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
        os.Exit(1)
    }
}

client.go:

package main

import (
    "fmt"
    "io/ioutil"
    "net"
    "os"
)

func main() {
    if len(os.Args) != 2 {
        fmt.Fprintf(os.Stderr, "Usage: %s host:port ", os.Args[0])
        os.Exit(1)
    }
    service := os.Args[1]
    tcpAddr, err := net.ResolveTCPAddr("tcp4", service)
    checkError(err)
    conn, err := net.DialTCP("tcp", nil, tcpAddr)
    checkError(err)
    _, err = conn.Write([]byte("HEAD / HTTP/1.0\r\n\r\n"))
    checkError(err)
    result, err := ioutil.ReadAll(conn)
    checkError(err)
    fmt.Println(string(result))
    os.Exit(0)
}
func checkError(err error) {
    if err != nil {
        fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
        os.Exit(1)
    }
}

shell:

./client 127.0.0.1:8888
Fatal error: WSARecv tcp 127.0.0.1:53141: An existing connection was forcibly closed by the remote host.

哪里有错误额?我是在本地测试的,服务端能接收到消息。

#

在win下一直不稳定,基本上十次请求有6次是报这个错误的,后来在server.go里加了两行代码,每次客户端连接过来,先用 conn.Read(b)把客户端发来的数据读出来,这样就不会报错了,不知道啥原理。

共 5 个回复


keepeye

不信邪了,去vps上试试

# 0

stevewang

把这行注释掉

_, err = conn.Write([]byte("HEAD / HTTP/1.0\r\n\r\n"))
# 1

stevewang

这个问题有一些复杂的原因,甚至服务端在linux或者windows上表现都不一样。 但是从程序设计的角度而言,不应该发送消息以后就立刻关闭连接。

# 2

keepeye

@stevewang 后来我在服务端返回消息之前先把客户端的消息读出来就ok了。

# 3

StevenDisonTomxen

我也遇到了同样的问题,但是根据二位的讨论,我尝试了一下。估计是和Channel相类似,当conn的一端有输出就必须另一方有输入。既有Write必须有Read。

# 4