| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- // Simple multi-thread/multi-core TCP server.
- package main
- import (
- "flag"
- "fmt"
- "net"
- "os"
- )
- 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.Listen("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
- }
- }
|