用Erlang开发web,很可能就会使用到mochiweb。mochiweb使用16个Erlang式的进程来监听tcp链接,使得任何链接进来都会很快得到处理。Golang跟Erlang很像,在这里实现了一个类似mochiweb的tcp监控链接,一个简单的echo服务器。先看代码。
1 package main
2
3 import (
4 "log"
5 "runtime"
6 "net"
7 )
8
9 func main() {
10
11 tcpAddr, err := net.ResolveTCPAddr("tcp", ":9988")
12 check_error(err)
13 tcpListener, err := net.ListenTCP("tcp", tcpAddr)
14 check_error(err)
15 for i := 0; i < 100; i++ {
16 go handle_tcp_accept(tcpListener)
17 }
18
19 select {}
20 }
21
22
23
24 func handle_tcp_accept(tcpListener *net.TCPListener) {
25 for {
26 tcpConn, err := tcpListener.AcceptTCP()
27 if err != nil {
28 log.Println("tcp accept failed!")
29 continue
30 } else {
31 connChan := make(chan []byte)
32 go write_tcp_conn(tcpConn, connChan)
33 go read_tcp_conn(tcpConn, connChan)
34 }
35 }
36
37 }
38
39
40 func read_tcp_conn(tcpConn *net.TCPConn, connChan chan []byte) {
41 buffer := make([]byte, 2048)
42 tcpConn.SetReadBuffer(2048)
43 for {
44 n, err := tcpConn.Read(buffer[0:])
45 if err != nil {
46 log.Println("one tcp connection read function failed!")
47 log.Println("one tcp connection close now!")
48 tcpConn.Close()
49 runtime.Goexit()
50 } else {
51 connChan <- buffer[0 : n-1]
52 }
53 }
54 }
55
56 func write_tcp_conn(tcpConn *net.TCPConn, connChan chan []byte) {
57 for {
58 msg := <-connChan
59 log.Println(string(msg))
60 tcpConn.Write([]byte(msg)[0 : len(msg)+1])
61 }
62 }
63
64
65
66
67 func check_error(err error) {
68 if err != nil {
69 log.Printf("Fatal error : %s", err.Error())
70 }
71
72 }
上面代码保存为multi_thread_echo.go, 使用gotool编译
go build multi_thread_echo.go
上面代码使用了100个goroutine来监听TCP链接,每个链接进来,都会新建2个goroutine,一个read,一个write。下面看看效果图:
参考:
1.Golang Away: TCP Chat Server
http://www.badgerr.co.uk/2011/06/20/golang-away-tcp-chat-server/
2.Network programming with Go
转贴请注明来自:格通
转载于:https://my.oschina.net/u/191928/blog/618654