Golang では、TCP は接続確立後にデフォルトで切断されます。これは、TCP プロトコル自体が接続の信頼性を保証する必要があるためです。接続が切断されると、新しい接続が再確立されます。ただし、TCP 接続を継続的に維持したい場合もあります。たとえば、同時実行性が高い状況では、頻繁に接続が確立されるとサーバーにさらなる負荷がかかります。では、Golang TCP が切断されないようにするにはどうすればよいでしょうか?
1. TCP キープアライブ
TCP キープアライブは、接続がまだアクティブであるかどうかを検出するために TCP プロトコルによって提供されるメカニズムです。 TCP 接続が一定期間データを送信しない場合、キープアライブ メカニズムは特定の検出パケットをピアに送信して、接続がまだ存在するかどうかを確認します。ピアがプローブ パケットに応答しない場合、ピアは切断されたとみなされ、接続はアクティブに閉じられます。ピアがプローブ パケットに応答できる場合、接続はまだ存在します。 TCP Keep-Alive メカニズムを使用して、Golang TCP 非切断を実現できます。
1.1 TCP キープアライブを有効にする
TCP キープアライブを有効にするには、ソケットのプロパティを設定する必要があります。 Golang は、ネット パッケージの TCPConn 構造体を使用して TCP 接続を表現できます。TCPConn は、TCP 接続を操作するための多くのメソッドを提供します。このうち、SetKeepAlive メソッドを使用すると、TCP Keep-Alive を設定できます。
サンプル コードは次のとおりです。
conn, err := net.Dial("tcp", "127.0.0.1:8080") if err != nil { fmt.Println("dial error:", err) return } tcpConn := conn.(*net.TCPConn) // 设置为开启 TCP KeepAlive,默认为不开启 tcpConn.SetKeepAlive(true)
1.2 TCP キープアライブ パラメータの設定
TCP キープアライブには 3 つのパラメータがあり、設定を通じてこれらのパラメータを設定できます。 TCPConnのメソッド。これらは、KeepAlive、KeepAlivePeriod、および KeepAliveCount です。
これら 3 つのパラメータは、実際のニーズに応じて設定できます。
サンプル コードは次のとおりです。
tcpConn.SetKeepAlive(true) // 开启 TCP Keep-Alive tcpConn.SetKeepAlivePeriod(time.Duration(30) * time.Second) // 设置探测包发送时间间隔为 30 秒 tcpConn.SetKeepAliveCount(3) // 设置探测包的发送次数为 3
1.3 キープアライブ検出パケットの送信頻度
デフォルトでは、キープアライブ検出パケットの送信頻度は、オペレーティング·システム。ほとんどのオペレーティング システムでは、TCP キープアライブ プローブ パケットは 2 時間ごとに送信されます。頻度を変更する必要がある場合は、オペレーティング システムのパラメータを変更することで実現できます。 Linux オペレーティング システムでは、proc ファイル システムのパラメータを変更することで、TCP キープアライブ検出パケットの送信頻度を変更できます。
2. 長い接続を使用する
Golang TCP の非切断を実現するもう 1 つの方法は、長い接続を使用することです。長い接続とは、クライアントとサーバー間の中断のない接続を指します。長期接続モードでは、クライアントがサーバーとの接続を確立した後、クライアントはいつでもリクエストを送信でき、サーバーもいつでも応答を送信できます。これにより、接続を頻繁に確立するときに発生するオーバーヘッドが軽減され、サーバーのパフォーマンスが向上します。
長い接続の実装方法について、簡単なサンプルコードを参考にさせていただきます。
package main import ( "bufio" "fmt" "net" ) func main() { listen, err := net.Listen("tcp", ":8080") if err != nil { panic(err) } for { conn, err := listen.Accept() if err != nil { continue } go handle(conn) } } func handle(conn net.Conn) { defer conn.Close() reader := bufio.NewReader(conn) for { data, err := reader.ReadString(' ') if err != nil { return } response := fmt.Sprintf("echo: %s", data) conn.Write([]byte(response)) } }
上記のサンプル コードでは、TCP サービスを開始することでクライアントのリクエストを受け入れます。クライアントがサーバーとの接続を確立すると、サーバーはループを通じてクライアントのリクエストを受信し、応答を返します。サーバーとクライアント間の接続は積極的に切断されないため、クライアントはいつでもサーバーにリクエストを送信できます。
3. 概要
この記事では、Golang TCP の非切断を実現するための 2 つの方法、つまり TCP Keep-Alive メカニズムを使用する方法と長い接続を使用する方法を紹介します。実際の開発では、実際の状況に応じて自分に合った方法を選択する必要があります。 TCP 接続を軽くしか使用しない場合は、TCP キープアライブを使用することをお勧めします。リクエストを頻繁に送信する必要がある場合は、長い接続を使用することをお勧めします。どの方法を使用する場合でも、実際のアプリケーションでは、セキュリティの抜け穴を避けるために、接続のセキュリティの標準化と保護に注意を払う必要があります。
以上がgolang tcp が切断されないの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。