63

小さなTCPサーバーを実装しています。クライアントの 1 つが閉鎖されたかどうかを知るにはどうすればよいですか? 読み取りまたは書き込みを試みて、errnil かどうかを確認する必要がありますか?

4

6 に答える 6

75

そのスレッド「TCP 接続が閉じていることを確実に検出するための最良の方法」、net.Connfor ' ' を使用 (またはまたは他の多くのインスタンスcでも見られます):utils/ping.golocale-backend/server.go

one := make([]byte, 1)
c.SetReadDeadline(time.Now())
if _, err := c.Read(one); err == io.EOF {
  l.Printf(logger.LevelDebug, "%s detected closed LAN connection", id)
  c.Close()
  c = nil
} else {
  var zero time.Time
  c.SetReadDeadline(time.Now().Add(10 * time.Millisecond))
}

タイムアウトを検出するために、次のことを提案します。

if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
  ...

2019 年の更新:コメントでのtuxedo25の言及:

go 1.7 以降では、ゼロ バイトの読み取りはすぐに返され、エラーが返されることはありません。
少なくとも 1 バイトを読み取る必要があります。

commit 5bcdd63を参照し、issue 15735に進みます

netio.EOF:ゼロバイト読み取りから戻らない

于 2012-10-05T07:22:27.847 に答える
17

そこから読み込もうとすると、閉じているとエラーがスローされます。必要に応じて優雅に処理してください!

与えすぎるリスクについて:

func Read(c *net.Conn, buffer []byte) bool {
    bytesRead, err := c.Read(buffer)
    if err != nil {
        c.Close()
        log.Println(err)
        return false
    }
    log.Println("Read ", bytesRead, " bytes")
    return true
}

以下は、net パッケージを使用して小さな TCP「チャット サーバー」を作成するための優れた紹介です。

Golang Away: TCP チャット サーバー

于 2012-10-05T07:17:22.787 に答える
-4
        _, err := conn.Read(make([]byte, 0))
        if err!=io.EOF{
            // this connection is invalid
            logger.W("conn closed....",err)

        }else{
            byt, _:= ioutil.ReadAll(conn);
        }
于 2016-10-17T08:58:19.273 に答える