mirror of
https://github.com/unknwon/the-way-to-go_ZH_CN.git
synced 2025-08-12 01:21:38 +08:00
04.4.md
This commit is contained in:
86
eBook/examples/chapter_15/simple_tcp_server.go
Normal file
86
eBook/examples/chapter_15/simple_tcp_server.go
Normal file
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* Simple multi-thread/multi-core TCP server.
|
||||
*
|
||||
*/
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"net"
|
||||
"fmt"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
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 syscall.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
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user