這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
golang對並發的支援非常好,就是因為他有一個goroutine機制和channel機制,實現並發情境輕鬆高效。
下面我們實現一個聊天室程式,代碼不多,但是功能很強大
//代碼轉載自:http://blog.csdn.net/ygrx/article/details/11773151package mainimport ("fmt""net""os")////////////////////////////////////////////////////////////錯誤檢查//////////////////////////////////////////////////////////func checkError(err error, info string) (res bool) {if err != nil {fmt.Println(info + " " + err.Error())return false}return true}////////////////////////////////////////////////////////////伺服器端接收資料線程//參數://資料連線 conn//通訊通道 messages//////////////////////////////////////////////////////////func Handler(conn net.Conn, messages chan string) {fmt.Println("connection is connected from ...", conn.RemoteAddr().String())buf := make([]byte, 1024)for {lenght, err := conn.Read(buf)if checkError(err, "Connection") == false {conn.Close()break}if lenght > 0 {buf[lenght] = 0}//fmt.Println("Rec[",conn.RemoteAddr().String(),"] Say :" ,string(buf[0:lenght]))reciveStr := string(buf[0:lenght])messages <- reciveStr}}////////////////////////////////////////////////////////////伺服器發送資料的線程////參數//串連字典 conns//資料通道 messages//////////////////////////////////////////////////////////func echoHandler(conns *map[string]net.Conn, messages chan string) {for {msg := <-messagesfmt.Println(msg)for key, value := range *conns {fmt.Println("connection is connected from ...", key)_, err := value.Write([]byte(msg))if err != nil {fmt.Println(err.Error())delete(*conns, key)}}}}////////////////////////////////////////////////////////////啟動伺服器//參數//連接埠 port//////////////////////////////////////////////////////////func StartServer(port string) {service := ":" + port //strconv.Itoa(port);tcpAddr, err := net.ResolveTCPAddr("tcp4", service)checkError(err, "ResolveTCPAddr")l, err := net.ListenTCP("tcp", tcpAddr)checkError(err, "ListenTCP")conns := make(map[string]net.Conn)messages := make(chan string, 10)//啟動伺服器廣播線程go echoHandler(&conns, messages)for {fmt.Println("Listening ...")conn, err := l.Accept()checkError(err, "Accept")fmt.Println("Accepting ...")conns[conn.RemoteAddr().String()] = conn//啟動一個新線程go Handler(conn, messages)}}////////////////////////////////////////////////////////////用戶端發送線程//參數//發送串連 conn//////////////////////////////////////////////////////////func chatSend(conn net.Conn) {var input stringusername := conn.LocalAddr().String()for {fmt.Scanln(&input)if input == "/quit" {fmt.Println("ByeBye..")conn.Close()os.Exit(0)}lens, err := conn.Write([]byte(username + " Say :::" + input))fmt.Println(lens)if err != nil {fmt.Println(err.Error())conn.Close()break}}}////////////////////////////////////////////////////////////用戶端啟動函數//參數//遠程ip地址和連接埠 tcpaddr//////////////////////////////////////////////////////////func StartClient(tcpaddr string) {tcpAddr, err := net.ResolveTCPAddr("tcp4", tcpaddr)checkError(err, "ResolveTCPAddr")conn, err := net.DialTCP("tcp", nil, tcpAddr)checkError(err, "DialTCP")//啟動用戶端發送線程go chatSend(conn)//開始用戶端輪訓buf := make([]byte, 1024)for {lenght, err := conn.Read(buf)if checkError(err, "Connection") == false {conn.Close()fmt.Println("Server is dead ...ByeBye")os.Exit(0)}fmt.Println(string(buf[0:lenght]))}}////////////////////////////////////////////////////////////主程式////參數說明://啟動伺服器端: Chat server [port]eg: Chat server 9090//啟動用戶端: Chat client [Server Ip Addr]:[Server Port] eg: Chat client 192.168.0.74:9090//////////////////////////////////////////////////////////func main() {fmt.Println(os.Args)if len(os.Args) != 3 {fmt.Println("Wrong pare")os.Exit(0)}if os.Args[1] == "server" && len(os.Args) == 3 {StartServer(os.Args[2])}if os.Args[1] == "client" && len(os.Args) == 3 {StartClient(os.Args[2])}}
只需要在命令列輸入例如:go run main.go server 9000 這樣的命令,就可以開啟服務端監聽。
假設server的ip為192.168.1.3,那麼輸入:go run main.go client 192.168.1.3:9000即可串連到伺服器並進入聊天室。