Bläddra i källkod

Create simple_tcp_server.go

glight2000 10 år sedan
förälder
incheckning
e5c4b4a3ce
1 ändrade filer med 77 tillägg och 0 borttagningar
  1. 77 0
      eBook/examples/chapter_15/simple_tcp_server.go

+ 77 - 0
eBook/examples/chapter_15/simple_tcp_server.go

@@ -0,0 +1,77 @@
+// Simple multi-thread/multi-core TCP server.
+package main
+
+import (
+	"flag"
+	"fmt"
+	"os"
+	"net"
+)
+
+const maxRead = 25
+
+func main() {
+	flag.Parse()
+	if flag.NArg() != 2 {
+		panic("usage: host port")
+	}
+	hostAndPort := fmt.Sprintf("%s:%s", flag.Arg(0), flag.Arg(1))
+	listener := initServer(hostAndPort)
+	for {
+		conn, err := listener.Accept()
+		checkError(err, "Accept: ")
+		go connectionHandler(conn)
+	}
+}
+func initServer(hostAndPort string) *net.TCPListener {
+	serverAddr, err := net.ResolveTCPAddr("tcp", hostAndPort)
+	checkError(err, "Resolving address:port failed: '"+hostAndPort+"'")
+	listener, err := net.ListenTCP("tcp", serverAddr)
+	checkError(err, "ListenTCP: ")
+	println("Listening to: ", listener.Addr().String())
+	return listener
+}
+func connectionHandler(conn net.Conn) {
+	connFrom := conn.RemoteAddr().String()
+	println("Connection from: ", connFrom)
+	sayHello(conn)
+	for {
+		var ibuf []byte = make([]byte, maxRead+1)
+		length, err := conn.Read(ibuf[0:maxRead])
+		ibuf[maxRead] = 0 // to prevent overflow
+		switch err {
+		case nil:
+			handleMsg(length, err, ibuf)
+		case os.EAGAIN: // try again
+			continue
+		default:
+			goto DISCONNECT
+		}
+	}
+DISCONNECT:
+	err := conn.Close()
+	println("Closed connection: ", connFrom)
+	checkError(err, "Close: ")
+}
+func sayHello(to net.Conn) {
+	obuf := []byte{'L', 'e', 't', '\'', 's', ' ', 'G', 'O', '!', '\n'}
+	wrote, err := to.Write(obuf)
+	checkError(err, "Write: wrote "+string(wrote)+" bytes.")
+}
+func handleMsg(length int, err error, msg []byte) {
+	if length > 0 {
+		print("<", length, ":")
+		for i := 0; ; i++ {
+			if msg[i] == 0 {
+				break
+			}
+			fmt.Printf("%c", msg[i])
+		}
+		print(">")
+	}
+}
+func checkError(error error, info string) {
+	if error != nil {
+		panic("ERROR: " + info + " " + error.Error()) // terminate program
+	}
+}