ホームページ > バックエンド開発 > Golang > Go で Unix ソケットを使用した双方向通信を実現するにはどうすればよいですか?

Go で Unix ソケットを使用した双方向通信を実現するにはどうすればよいですか?

Mary-Kate Olsen
リリース: 2024-12-02 01:25:11
オリジナル
1025 人が閲覧しました

How to Achieve Bidirectional Communication with Unix Sockets in Go?

Go の双方向 Unix ソケット

Go に Unix ソケットを実装する場合、クライアントとサーバーの両方がデータを送受信できるようにするための双方向通信チャネルを確立することが不可欠です。 。この記事では、Unix ソケットを使用するときに発生する基本的な問題、つまり一方向のみのデータ送信につながる単方向接続について説明します。

問題の理解

提供されたコード例では、サーバーは次からデータを受信できます。クライアントに応答しましたが、データの応答に失敗しました。この問題は、クライアント コード内の c.Read() 呼び出しの後に c.Write() 呼び出しが続かないことが原因で発生します。その結果、クライアントはサーバーの応答を読み取ることができず、単方向接続であるかのような錯覚を引き起こします。

問題の解決

双方向通信を確立するには、クライアントとサーバーの両方を変更する必要があります。 code.

サーバーの変更

変更されたサーバー コードでは、場合に備えて接続を正常に閉じる処理を行う defer ステートメントが導入されています。エラーの。さらに、必要に応じて、break を利用してリーダー ゴルーチンを終了します。

package main

import (
    "log"
    "net"
)

func echoServer(c net.Conn) {
    defer c.Close()

    for {
        buf := make([]byte, 512)
        nr, err := c.Read(buf)
        if err != nil {
            return
        }

        data := buf[0:nr]
        println("Server got:", string(data))
        _, err = c.Write(data)
        if err != nil {
            log.Fatal("Write: ", err)
        }
    }
}

func main() {
    l, err := net.Listen("unix", "/tmp/echo.sock")
    if err != nil {
        log.Fatal("listen error:", err)
    }

    for {
        fd, err := l.Accept()
        if err != nil {
            log.Fatal("accept error:", err)
        }

        go echoServer(fd)
    }
}
ログイン後にコピー

クライアントの変更

変更されたクライアント コードは、サーバーから受信データを継続的に読み取るためのリーダー ゴルーチンを追加します。 defer ステートメントは、main 関数の終了時に接続が確実に閉じられるようにします。

package main

import (
    "io"
    "log"
    "net"
    "time"
)

func reader(r io.Reader) {
    defer r.(net.Conn).Close()  // Ensure connection is closed even on panic

    buf := make([]byte, 1024)
    for {
        n, err := r.Read(buf[:])
        if err != nil {
            return
        }
        println("Client got:", string(buf[0:n]))
    }
}

func main() {
    c, err := net.Dial("unix", "/tmp/echo.sock")
    if err != nil {
        log.Fatal(err)
    }

    go reader(c)

    for {
        _, err := c.Write([]byte("hi"))
        if err != nil {
            log.Fatal(err)
            break
        }
        time.Sleep(1e9)
    }
}
ログイン後にコピー

これらの変更により、クライアントとサーバーの通信が双方向になり、双方がシームレスにデータを送受信できるようになります。

以上がGo で Unix ソケットを使用した双方向通信を実現するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート