いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-327 (Go でキープアライブプローブを送信する (Windows, Linux, Keep Alive Probe))

関連記事

dotnet (.net framework) でキープアライブプローブを送信する (Windows, Linux, Keep Alive Probe) - いろいろ備忘録日記

概要

以下、自分用のメモです。忘れないうちにメモメモ。。。

ちょっと前に.net で キープアライブプローブを送信するやり方を調べる必要があり、調査ついでに以下のリポジトリを作っておきました。

github.com

んで、ついでに Go でもどうやるのかなって調べた結果を以下のリポジトリにまとめておきました。よかったらご参考まで。

github.com

以下、その内容を抜粋。

サンプル

サーバ側

とりあえず、接続を受け付けるものが必要なので、以下のようにしてListenするようにしておきます。

package main

import (
    "fmt"
    "net"
    "time"
)

func main() {
    if err := run(); err != nil {
        panic(err)
    }
}

func run() error {
    ln, err := net.Listen("tcp", ":12345")
    if err != nil {
        return fmt.Errorf("error: net.Listen (%w)", err)
    }
    defer ln.Close()

    for {
        conn, err := ln.Accept()
        if err != nil {
            return fmt.Errorf("error: ln.Accept (%w)", err)
        }

        go handle(conn)
    }
}

func handle(conn net.Conn) {
    defer conn.Close()
    time.Sleep(10 * time.Second)
}

受け付けたら何もせずにジーッとしておく

クライアント

こちらが今回の対象。ソケットを生成したらキープアライブの設定を行います。キープアライブの設定は *net.TCPConn に定義されているのでキャストして設定。

package main

import (
    "fmt"
    "net"
    "time"
)

func main() {
    if err := run(); err != nil {
        panic(err)
    }
}

func run() error {
    conn, err := net.Dial("tcp", ":12345")
    if err != nil {
        return fmt.Errorf("error: net.Dial (%w)", err)
    }
    defer conn.Close()

    tcpConn, ok := conn.(*net.TCPConn)
    if !ok {
        return fmt.Errorf("error: not *net.TCPConn")
    }

    // Set Keep-Alive
    {
        if err := tcpConn.SetKeepAlive(true); err != nil {
            return fmt.Errorf("error: tcpConn.SetKeepAlive (%w)", err)
        }

        if err := tcpConn.SetKeepAlivePeriod(2 * time.Second); err != nil {
            return fmt.Errorf("error: tcpConn.SetKeepAlivePeriod (%w)", err)
        }
    }

    time.Sleep(10 * time.Second)

    return nil
}

実行すると、以下のようなキャプチャが見れます。ちゃんとキープアライブプローブが送信されていますね。

実行方法については、上記のリポジトリを参照ください。

$ task capture
task: [capture] sudo tcpdump -i lo 'tcp and port 12345 and tcp[13] & 16 != 0 and tcp[12] & 15 = 0'
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes
07:42:59.109181 IP localhost.12345 > localhost.57006: Flags [S.], seq 1096637414, ack 3661790707, win 43690, options [mss 65495,sackOK,TS val 1727619187 ecr 1727619187,nop,wscale 7], length 0
07:42:59.109200 IP localhost.57006 > localhost.12345: Flags [.], ack 1, win 342, options [nop,nop,TS val 1727619187 ecr 1727619187], length 0
07:43:01.120277 IP localhost.57006 > localhost.12345: Flags [.], ack 1, win 342, options [nop,nop,TS val 1727621199 ecr 1727619187], length 0
07:43:01.120283 IP localhost.12345 > localhost.57006: Flags [.], ack 1, win 342, options [nop,nop,TS val 1727621199 ecr 1727619187], length 0
07:43:03.132273 IP localhost.57006 > localhost.12345: Flags [.], ack 1, win 342, options [nop,nop,TS val 1727623211 ecr 1727621199], length 0
07:43:03.132283 IP localhost.12345 > localhost.57006: Flags [.], ack 1, win 342, options [nop,nop,TS val 1727623211 ecr 1727619187], length 0
07:43:05.148284 IP localhost.57006 > localhost.12345: Flags [.], ack 1, win 342, options [nop,nop,TS val 1727625227 ecr 1727623211], length 0
07:43:05.148295 IP localhost.12345 > localhost.57006: Flags [.], ack 1, win 342, options [nop,nop,TS val 1727625227 ecr 1727619187], length 0
07:43:07.164286 IP localhost.57006 > localhost.12345: Flags [.], ack 1, win 342, options [nop,nop,TS val 1727627243 ecr 1727625227], length 0
07:43:07.164292 IP localhost.12345 > localhost.57006: Flags [.], ack 1, win 342, options [nop,nop,TS val 1727627243 ecr 1727619187], length 0
07:43:09.116306 IP localhost.57006 > localhost.12345: Flags [F.], seq 1, ack 1, win 342, options [nop,nop,TS val 1727629195 ecr 1727627243], length 0
07:43:09.116396 IP localhost.12345 > localhost.57006: Flags [F.], seq 1, ack 2, win 342, options [nop,nop,TS val 1727629195 ecr 1727629195], length 0
07:43:09.116440 IP localhost.57006 > localhost.12345: Flags [.], ack 2, win 342, options [nop,nop,TS val 1727629195 ecr 1727629195], length 0

Linuxで実行すると、送信されるキープアライブプローブはペイロードが0バイトで送信されます。

Windowsで実行すると、送信されるキープアライブプローブはペイロードが1バイトで0x00固定で送信されます。

参考情報

Goのおすすめ書籍

Go言語による並行処理

Go言語による並行処理

Amazon


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。