技術向上

プログラミングの学び、気になるテクノロジーやビジネストレンドを発信

TCP SetDeadline【Go】

net.ConnのSetDeadline()メソッドを使うと、
接続の有効期限を指定することができます。

func main() {
    li, err := net.Listen("tcp", ":8080")
    if err != nil {
        log.Fatal(err)
    }

    for {
        conn, err := li.Accept()
        if err != nil {
            log.Fatal(err)
        }
        go handle(conn)
    }
}

func handle(conn net.Conn) {
    err := conn.SetDeadline(time.Now().Add(10 * time.Second))
    if err != nil {
        log.Fatal(err)
    }
    scanner := bufio.NewScanner(conn)

    for scanner.Scan() {
        ln := scanner.Text()
        fmt.Println(ln)
        fmt.Fprintf(conn, "You said, %v", ln)
    }
    if err := scanner.Err(); err != nil {
        fmt.Println(err)    // クライアントが接続してからSetDeadlineの期限を超過すると、ここを通るため、log.Fatal()を使うと、サーバープログラムが終了してしまうので注意
    }
    defer conn.Close()
}


これはあくまで、クライアントの期限であり、サーバーのプログラムの有効期限ではありません。
クライアントが接続を開始してから指定時間を過ぎると、クライアント側の接続が切れます。
複数クライアントを同時に接続することは、もちろん可能ですし、
有効期限も、それぞれのクライアントで管理されます。

scanner.Err()は、1行あたりのサイズが上限を超えてエラーになった場合に原因を把握するために用意しています。
ただ、SetDeadlineの期限切れるとこの場所を通過するため、
log.Fatal()を用いるとサーバープログラムが終了してしまうので注意が必要です。