bufio packageのScannerを使って1行ずつ読み込むことができます。
TCP接続した情報を読み込む例を示します。
main.goです。
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) {
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
defer conn.Close()
}
上記を実行し、ブラウザ上で:8080にアクセスすると、接続情報が出力されます。
別のターミナルからtelnetを使ってlocalhost 8080に接続すると、
そのターミナルに入力した値が、そのままファイル実行側のターミナルに出力されます。
また、forループの中で、Fprintを使用すると書き込みも行うことができます。
for scanner.Scan() {
fmt.Println(scanner.Text())
fmt.Fprintf(conn, "You said, %v", scanner.Text())
}
bufio.NewScannerでポインタを作成した後に、Splitメソッドを使うと、
行の区切り方を指定することもできます。
scanner := bufio.NewScanner(conn) scanner.Split(bufio.ScanWords) // 単語で区切る
bufio.Scannerは、ReadString()やReadBytes()よりも記述量が少なくなり、便利ではありますが、1行のデータ量が、上限を超えてしまうとscanを中断してしまう、という問題があります。デフォルトですと、その上限は65536バイトです。
あらかじめ1行のサイズ上限がわかっている場合には、scanner.Buffer()を使って最大のバッファサイズを指定します。
const (
initialBufSize = 10000
maxBufSize = 1000000
)
func handle(conn net.Conn) {
scanner := bufio.NewScanner(conn)
buf := make([]byte, initialBufSize)
scanner.Buffer(buf, maxBufSize)
...
}
scanが始まった後にscanner.Buffer()を実行するとpanicが発生します。
あらかじめ1行の上限がわからない場合は、bufio.Reader.ReadBytes()などを使用するのがよいでしょう。
参考