mirror of
https://github.com/unknwon/the-way-to-go_ZH_CN.git
synced 2025-08-12 07:02:11 +08:00
Create simple_tcp_server.go
This commit is contained in:
77
eBook/examples/chapter_15/simple_tcp_server.go
Normal file
77
eBook/examples/chapter_15/simple_tcp_server.go
Normal file
@@ -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
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user