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 サイトの他の関連記事を参照してください。