TCP Server
bufio fmt net strings timeThe net package provides the building blocks under net/http: listeners and connections. A net.Conn is an io.Reader and an io.Writer, so everything from the Readers and Writers example applies. Here is a line-based echo server, with a client in the same program.
package main
import (
"bufio"
"fmt"
"net"
"strings"
"time"
)handle serves one connection: it reads lines and answers each one in upper case.
func handle(conn net.Conn) {
defer conn.Close()
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
line := scanner.Text()
if line == "quit" {
fmt.Fprintln(conn, "bye")
return
}
fmt.Fprintln(conn, strings.ToUpper(line))
}
}
func main() {net.Listen opens a listening socket. Port 0 picks a free port.
ln, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
panic(err)
}
defer ln.Close()Accept connections in a loop, serving each in its own goroutine so one slow client cannot block the others.
go func() {
for {
conn, err := ln.Accept()
if err != nil {
return // the listener was closed
}
go handle(conn)
}
}()net.Dial connects a client. DialTimeout bounds the time to connect.
conn, err := net.DialTimeout("tcp", ln.Addr().String(), time.Second)
if err != nil {
panic(err)
}
defer conn.Close()Deadlines make reads and writes fail instead of hanging forever.
conn.SetDeadline(time.Now().Add(5 * time.Second))
reader := bufio.NewReader(conn)
for _, msg := range []string{"hello", "tcp in go", "quit"} {
fmt.Fprintln(conn, msg)
reply, err := reader.ReadString('\n')
if err != nil {
panic(err)
}
fmt.Printf("sent %q, got %q\n", msg, strings.TrimSpace(reply))
}After "quit" the server closes the connection, so the next read sees EOF.
_, err = reader.ReadString('\n')
fmt.Println("after quit:", err)net also resolves addresses and splits host and port.
host, port, _ := net.SplitHostPort("example.com:443")
fmt.Println(host, port, net.ParseIP("192.168.1.10").IsPrivate())
}$ go run ./84_tcp_server sent "hello", got "HELLO" sent "tcp in go", got "TCP IN GO" sent "quit", got "bye" after quit: EOF example.com 443 true