simple_tcp_server_v1.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // Simple multi-thread/multi-core TCP server.
  2. package main
  3. import (
  4. "flag"
  5. "fmt"
  6. "net"
  7. "syscall"
  8. )
  9. const maxRead = 25
  10. func main() {
  11. flag.Parse()
  12. if flag.NArg() != 2 {
  13. panic("usage: host port")
  14. }
  15. hostAndPort := fmt.Sprintf("%s:%s", flag.Arg(0), flag.Arg(1))
  16. listener := initServer(hostAndPort)
  17. for {
  18. conn, err := listener.Accept()
  19. checkError(err, "Accept: ")
  20. go connectionHandler(conn)
  21. }
  22. }
  23. func initServer(hostAndPort string) *net.TCPListener {
  24. serverAddr, err := net.ResolveTCPAddr("tcp", hostAndPort)
  25. checkError(err, "Resolving address:port failed: '"+hostAndPort+"'")
  26. listener, err := net.ListenTCP("tcp", serverAddr)
  27. checkError(err, "ListenTCP: ")
  28. println("Listening to: ", listener.Addr().String())
  29. return listener
  30. }
  31. func connectionHandler(conn net.Conn) {
  32. connFrom := conn.RemoteAddr().String()
  33. println("Connection from: ", connFrom)
  34. sayHello(conn)
  35. for {
  36. var ibuf []byte = make([]byte, maxRead+1)
  37. length, err := conn.Read(ibuf[0:maxRead])
  38. ibuf[maxRead] = 0 // to prevent overflow
  39. switch err {
  40. case nil:
  41. handleMsg(length, err, ibuf)
  42. case syscall.Errno(0xb): // try again
  43. continue
  44. default:
  45. goto DISCONNECT
  46. }
  47. }
  48. DISCONNECT:
  49. err := conn.Close()
  50. println("Closed connection: ", connFrom)
  51. checkError(err, "Close: ")
  52. }
  53. func sayHello(to net.Conn) {
  54. obuf := []byte{'L', 'e', 't', '\'', 's', ' ', 'G', 'O', '!', '\n'}
  55. wrote, err := to.Write(obuf)
  56. checkError(err, "Write: wrote "+string(wrote)+" bytes.")
  57. }
  58. func handleMsg(length int, err error, msg []byte) {
  59. if length > 0 {
  60. print("<", length, ":")
  61. for i := 0; ; i++ {
  62. if msg[i] == 0 {
  63. break
  64. }
  65. fmt.Printf("%c", msg[i])
  66. }
  67. print(">")
  68. }
  69. }
  70. func checkError(error error, info string) {
  71. if error != nil {
  72. panic("ERROR: " + info + " " + error.Error()) // terminate program
  73. }
  74. }