main.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // Solution to part 3 of the Whispering Gophers code lab.
  2. //
  3. // This program listens on the host and port specified by the -listen flag.
  4. // For each incoming connection, it launches a goroutine that reads and decodes
  5. // JSON-encoded messages from the connection and prints them to standard
  6. // output.
  7. //
  8. // You can test this program by running it in one terminal:
  9. // $ part3 -listen=localhost:8000
  10. // And running part2 in another terminal:
  11. // $ part2 -dial=localhost:8000
  12. // Lines typed in the second terminal should appear as JSON objects in the
  13. // first terminal.
  14. //
  15. package main
  16. import (
  17. "bufio"
  18. "encoding/json"
  19. "flag"
  20. "fmt"
  21. "io"
  22. "log"
  23. "net"
  24. )
  25. var listenAddr = flag.String("listen", "localhost:8000", "host:port to listen on")
  26. type Message struct {
  27. Body string
  28. }
  29. func main() {
  30. flag.Parse()
  31. // Create a net.Listener listening from the address in the "listen" flag.
  32. l, err := net.Listen("tcp4", *listenAddr)
  33. if err != nil {
  34. log.Fatal(err)
  35. }
  36. for {
  37. // Accept a new connection from the listener.
  38. c, err := l.Accept()
  39. if err != nil {
  40. log.Fatal(err)
  41. }
  42. go serve(c)
  43. }
  44. }
  45. func serve(c net.Conn) {
  46. // Use defer to Close the connection when this function returns.
  47. defer c.Close()
  48. // Create a new json.Decoder reading from the connection.
  49. d := json.NewDecoder(bufio.NewReader(c)) // NewDecoder(c) would loop on EOF
  50. for {
  51. // Create an empty message.
  52. m := Message{}
  53. // Decode a new message into the variable you just created.
  54. err := d.Decode(&m)
  55. if err == io.EOF {
  56. break
  57. }
  58. if err != nil {
  59. log.Fatal(err)
  60. }
  61. // Print the message to the standard output.
  62. fmt.Println(m)
  63. }
  64. log.Println("Closing connection on EOF.")
  65. }