golang tcp が切断されない

王林
リリース: 2023-05-15 10:21:37
オリジナル
1112 人が閲覧しました

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 です。

  • KeepAlive: TCP キープアライブを有効にするかどうかを示します。デフォルトでは有効になっていません。
  • 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 サイトの他の関連記事を参照してください。

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