Goならわかるシステムプログラミング:第6章 TCPソケットとHTTPの実装

01 Mar 2022, 23:40 By mosuke5

こんにちは、もーすけです。
「Goならわかるシステムプログラミング」を読み進めています。とてもいい本です。 読み進めながら実験したことなどを書いていきます。同じ本を読んでいる人の参考(寄り道?)になればと思います。 今回は「TCPソケットとHTTPの実装」です。


Goならわかるシステムプログラミングの学習シリーズ

「6.4 ソケット通信の基本構造」

「6.4 ソケット通信の基本構造」では、TCPサーバの実装の解説がありますが、さらっと流されているのでせっかくなので手元で動かして理解を深めてから、「6.5 Go言語でのHTTPサーバを実装する」に移りたいと思います。

Minimum TCPサーバ

本当に最小限のTCPサーバの実装。
TCPリクエストがくると処理はしますが、プログラムが終了してしまうため一度しか応答できません。 書籍ではTCPのクライアントもGoで書いていますが、もっと手軽に nc コマンドでさくっと試してみましょう。

package main

import (
	"io"
	"net"
)

func main() {
	ln, err := net.Listen("tcp", ":8080")
	if err != nil {
		panic(err)
	}
	conn, err := ln.Accept()
	if err != nil {
		panic(err)
	}

  // 2章 io.Writerで学んだことを復習
	io.WriteString(conn, "hello from my tcp server!")
}

nc コマンドでリクエスト送信後、リクエストは返ってきますが、2度目の送信ではレスポンスがなく、exitコードも1(エラー)であることが確認できました。

$ nc localhost 8080
hello from my tcp server!

$ nc localhost 8080
$ echo $?
1

プログラムを終了させないTCPサーバ

次は、せめて何度でもリクエストに答えられるように for で繰り返しリクエストに応答します。 しかし、一度に1リクエストしか受け付けられません。その様子がわかるように処理にsleep処理を入れて、ふたつのクライアントから接続にいきます。

package main

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

func main() {
	ln, err := net.Listen("tcp", ":8080")
	fmt.Println("TCP server is running on localhost:8080")
	if err != nil {
		panic(err)
	}

	for {
		conn, err := ln.Accept()
		if err != nil {
			panic(err)
		}
		io.WriteString(conn, "processing...")
		time.Sleep(3 * time.Second)
		io.WriteString(conn, "done")
		conn.Close()
	}
}

片方の処理が終わってから、もう片方の処理が実行されることを確認できます。

go-tcp-server-test

複数リクエストを処理できるTCPサーバ

続いて、今度は複数リクエストを同時に処理できるように改良します。 実処理部分をgoroutineで別スレッド処理にすることで実現できるでしょう。

package main

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

func main() {
	ln, err := net.Listen("tcp", ":8080")
	fmt.Println("TCP server is running on localhost:8080")
	if err != nil {
		panic(err)
	}

	for {
		conn, err := ln.Accept()
		if err != nil {
			panic(err)
		}

		// goroutineでノンブロッキング処理
		go func() {
			io.WriteString(conn, "processing...")
			time.Sleep(3 * time.Second)
			io.WriteString(conn, "done")
			conn.Close()
		}()
	}
}

go-tcp-server-test-2

記事の内容に関連した相談、仕事依頼したい New

記事の内容やクラウドネイティブ技術に関する相談、仕事依頼を開始しました。
仕事依頼、相談をしてみる

記事へのフィードバック

本記事に対して、フィードバックあればこちらのフォームからご記入ください。
記事の内容にフィードバックしてみる

このエントリーをはてなブックマークに追加