mirror of
https://github.com/unknwon/the-way-to-go_ZH_CN.git
synced 2025-08-12 07:02:11 +08:00
* Update 07.3.md * Update 07.3.md * Update 07.6.md * fix few problems * Update 10.6 and 10.8 * Update 11.6 and 11.7 * fix some problems before Chap13 * add a dot * Update 13.9 * little improve * Thoughts about time.After * Thoughts about time.After * Fix 14.6,15.1
83 lines
1.7 KiB
Go
83 lines
1.7 KiB
Go
// 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
|
|
}
|
|
}
|