「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > Go のノンブロッキング TCP 読み取りで不完全なデータ受信を処理するにはどうすればよいですか?

Go のノンブロッキング TCP 読み取りで不完全なデータ受信を処理するにはどうすればよいですか?

2024 年 11 月 8 日に公開
ブラウズ:691

How to Handle Incomplete Data Reception in Go\'s Non-Blocking TCP Reads?

Go TCP 読み取りはノンブロッキングです: 不完全なデータ受信に対処する

Go では、TCP 読み取りはノンブロッキングです。つまり、すぐに戻ります。たとえそれが予想よりも少なかったとしても、利用可能なデータがあれば。この動作は、必要な量のデータが受信されるまで待機する C のブロッキング読み取りとは異なります。

非ブロッキング読み取りの理由

TCP はバイトのストリームとして動作します。 、送信中に断片化される可能性があります。したがって、受信したバイト数のみに基づいてメッセージの終わりを判断することは不可能です。これには、メッセージ境界を決定するためのカスタム区切り文字またはその他のメカニズムが必要です。

不完全なデータに対する解決策

特定のバイト数を読み取るには、io.ReadAtLeast または io.ReadFull を使用します。 。任意の条件については、エラーがなくなるか、指定された条件が満たされるまで、Read 呼び出しをループします。

例:

package main

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

func main() {
    conn, _ := net.Dial("tcp", "127.0.0.1:4243")

    // Set a deadline to prevent hanging reads
    _ = conn.SetReadDeadline(time.Now().Add(10 * time.Second))

    // Loop to read until a newline is encountered
    for {
        buf := make([]byte, 512)
        n, err := conn.Read(buf)
        if err != nil {
            fmt.Println(err)
            break
        }
        if n > 0 {
            str := string(buf[:n])
            if str[len(str)-1] == '\n' {
                fmt.Println(str)
                break
            }
        }
    }
}

その他の考慮事項

  • 1 回の書き込みで複数のパケットが発生する可能性を処理します。
  • 区切り文字または他の方法を使用してメッセージ境界を定義します。 .
  • テキストベースのプロトコルに net/textproto の使用を検討します。
  • リソースの枯渇を防ぐためにタイムアウトまたは期限を実装します。
  • マスキングの問題を回避するために、ネットワーク操作からのすべてのエラーを確認します。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3