main.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Solution to part 6 of the Whispering Gophers code lab.
  2. //
  3. // This program is functionally equivalent to part 5,
  4. // but the reading from standard input and writing to the
  5. // network connection are done by separate goroutines.
  6. //
  7. package main
  8. import (
  9. "bufio"
  10. "encoding/json"
  11. "flag"
  12. "fmt"
  13. "log"
  14. "net"
  15. "os"
  16. "code.osinet.fr/fgm/whispering_gophers/util"
  17. )
  18. var (
  19. listenAddr = flag.String("listen", "", "peer host:port")
  20. peerAddr = flag.String("peer", "", "peer host:port")
  21. self string
  22. )
  23. type Message struct {
  24. Addr string
  25. Body string
  26. }
  27. func main() {
  28. flag.Parse()
  29. var l net.Listener
  30. var err error
  31. // Create a new listener using util.Listen and put it in a variable named l.
  32. if *listenAddr == "" {
  33. l, err = util.ListenOnFirstUsableInterface()
  34. } else {
  35. l, err = net.Listen("tcp4", *listenAddr)
  36. }
  37. if err != nil {
  38. log.Fatal(err)
  39. }
  40. self = l.Addr().String()
  41. log.Println("Listening on", self)
  42. go dial(*peerAddr)
  43. go readInput()
  44. for {
  45. c, err := l.Accept()
  46. if err != nil {
  47. log.Fatal(err)
  48. }
  49. go serve(c)
  50. }
  51. }
  52. func serve(c net.Conn) {
  53. defer c.Close()
  54. d := json.NewDecoder(c)
  55. for {
  56. var m Message
  57. err := d.Decode(&m)
  58. if err != nil {
  59. log.Println(err)
  60. return
  61. }
  62. fmt.Printf("%#v\n", m)
  63. }
  64. }
  65. // Make a new channel of Messages.
  66. var peer = make(chan Message)
  67. func readInput() {
  68. s := bufio.NewScanner(os.Stdin)
  69. for s.Scan() {
  70. m := Message{
  71. Addr: self,
  72. Body: s.Text(),
  73. }
  74. // Send the message to the channel of messages.
  75. peer <- m
  76. }
  77. if err := s.Err(); err != nil {
  78. log.Fatal(err)
  79. }
  80. os.Exit(0)
  81. }
  82. func dial(addr string) {
  83. c, err := net.Dial("tcp", addr)
  84. if err != nil {
  85. log.Println(addr, err)
  86. return
  87. }
  88. defer c.Close()
  89. e := json.NewEncoder(c)
  90. /* Receive messages from the channel using range, storing them in the variable m. */
  91. for m := range peer {
  92. err := e.Encode(m)
  93. if err != nil {
  94. log.Println(addr, err)
  95. return
  96. }
  97. }
  98. }