74 lines
1.6 KiB
Go
74 lines
1.6 KiB
Go
// Solution to part 3 of the Whispering Gophers code lab.
|
|
//
|
|
// This program listens on the host and port specified by the -listen flag.
|
|
// For each incoming connection, it launches a goroutine that reads and decodes
|
|
// JSON-encoded messages from the connection and prints them to standard
|
|
// output.
|
|
//
|
|
// You can test this program by running it in one terminal:
|
|
// $ part3 -listen=localhost:8000
|
|
// And running part2 in another terminal:
|
|
// $ part2 -dial=localhost:8000
|
|
// Lines typed in the second terminal should appear as JSON objects in the
|
|
// first terminal.
|
|
//
|
|
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net"
|
|
)
|
|
|
|
var listenAddr = flag.String("listen", "localhost:8000", "host:port to listen on")
|
|
|
|
type Message struct {
|
|
Body string
|
|
}
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
|
|
// Create a net.Listener listening from the address in the "listen" flag.
|
|
l, err := net.Listen("tcp4", *listenAddr)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
for {
|
|
// Accept a new connection from the listener.
|
|
c, err := l.Accept()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
go serve(c)
|
|
}
|
|
}
|
|
|
|
func serve(c net.Conn) {
|
|
// Use defer to Close the connection when this function returns.
|
|
defer c.Close()
|
|
|
|
// Create a new json.Decoder reading from the connection.
|
|
d := json.NewDecoder(bufio.NewReader(c)) // NewDecoder(c) would loop on EOF
|
|
for {
|
|
// Create an empty message.
|
|
m := Message{}
|
|
// Decode a new message into the variable you just created.
|
|
err := d.Decode(&m)
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
// Print the message to the standard output.
|
|
fmt.Println(m)
|
|
}
|
|
log.Println("Closing connection on EOF.")
|
|
}
|