main.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // Solution to part 4 of the Whispering Gophers code lab.
  2. //
  3. // This program is a combination of parts 2 and 3.
  4. //
  5. // It listens on the host and port specified by the -listen flag.
  6. // For each incoming connection, it launches a goroutine that reads and decodes
  7. // JSON-encoded messages from the connection and prints them to standard
  8. // output.
  9. // It concurrently makes a connection the host and port specified by the -dial
  10. // flag, reads lines from standard input, and writes JSON-encoded messages to
  11. // the network connection.
  12. //
  13. // You can test it by running part3 in one terminal:
  14. // $ part3 -listen=localhost:8000
  15. // Running this program in another terminal:
  16. // $ part4 -listen=localhost:8001 -dial=localhost:8000
  17. // And running part2 in another terminal:
  18. // $ part2 -dial=localhost:8001
  19. // Lines typed in the second terminal should appear as JSON objects in the
  20. // first terminal, and those typed at the third terminal should appear in the
  21. // second.
  22. //
  23. package main
  24. import (
  25. "bufio"
  26. "encoding/json"
  27. "flag"
  28. "fmt"
  29. "log"
  30. "net"
  31. "os"
  32. )
  33. var (
  34. listenAddr = flag.String("listen", "", "host:port to listen on")
  35. dialAddr = flag.String("dial", "", "host:port to dial")
  36. )
  37. type Message struct {
  38. Body string
  39. }
  40. func main() {
  41. flag.Parse()
  42. // Launch dial in a new goroutine, passing in *dialAddr.
  43. if *dialAddr != "" {
  44. go dial(*listenAddr)
  45. } else {
  46. log.Println("Not dialing")
  47. }
  48. l, err := net.Listen("tcp", *listenAddr)
  49. if err != nil {
  50. log.Fatal(err)
  51. }
  52. for {
  53. c, err := l.Accept()
  54. if err != nil {
  55. log.Fatal(err)
  56. }
  57. go serve(c)
  58. }
  59. }
  60. func serve(c net.Conn) {
  61. defer c.Close()
  62. d := json.NewDecoder(c)
  63. for {
  64. var m Message
  65. err := d.Decode(&m)
  66. if err != nil {
  67. log.Println(err)
  68. return
  69. }
  70. fmt.Printf("%#v\n", m)
  71. }
  72. }
  73. func dial(addr string) {
  74. // put the contents of the main function from part 2 here.
  75. c, err := net.Dial("tcp4", *dialAddr)
  76. if err != nil {
  77. log.Fatal(err)
  78. }
  79. s := bufio.NewScanner(os.Stdin)
  80. e := json.NewEncoder(c)
  81. for s.Scan() {
  82. m := Message{Body: s.Text()}
  83. err := e.Encode(m)
  84. if err != nil {
  85. log.Fatal(err)
  86. }
  87. }
  88. if err := s.Err(); err != nil {
  89. log.Fatal(err)
  90. } else {
  91. os.Exit(0)
  92. }
  93. }