ホームページ  >  記事  >  バックエンド開発  >  Go のノンブロッキング TCP 読み取りで不完全なデータ受信を処理するにはどうすればよいですか?

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

DDD
DDDオリジナル
2024-11-04 16:05:02612ブラウズ

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

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

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

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

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

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

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

例:

<code class="go">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
            }
        }
    }
}</code>

その他の考慮事項

  • 1 回の書き込みで複数のパケットが存在する可能性を処理します。
  • 区切り文字またはその他のメソッドを使用してメッセージ境界を定義します。
  • テキストには net/textproto を使用することを検討してください。
  • リソースの枯渇を防ぐために、タイムアウトまたは期限を実装します。
  • マスキングの問題を回避するために、ネットワーク操作からのすべてのエラーを確認します。

以上がGo のノンブロッキング TCP 読み取りで不完全なデータ受信を処理するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。