今天介紹golang版本的通信基礎:基於TCP的客戶端和服務器實現,參考書籍:The Way To Go
那時學習java的時候也是做過通信的,當時是socket編程,服務器監聽某一個端口,然后客戶機去連接,簡單的聊天室就實現了。后來有變成多線程的聊天室,可以進行群聊什么的了,后期可以傳圖片傳音樂,加上UI那一塊兒,山寨QQ就OK了。現在我來用golang實現一下簡易的聊天室,實現了客戶機連接服務器,給服務器發消息,服務器接受消息,客戶機退出,服務器可以收到退出信息,以及多個客戶機同時連入一個服務器。主要的思路和java一樣的,服務器監聽某一個端口,客戶機去連接,然后發送消息就OK了。上代碼了。
package main
//服務器端
import (
"fmt"
"log"
"net" //支持通訊的包
)
//開始服務器
func startServer() {
//連接主機、端口,采用tcp方式通信,監聽7777端口
listener, err := net.Listen("tcp", "localhost:7777")
checkError(err)
fmt.Println("建立成功!")
for {
//等待客戶端接入
conn, err := listener.Accept()
checkError(err)
//開一個goroutines處理客戶端消息,這是golang的特色,實現並發就只go一下就好
go doServerStuff(conn)
}
}
//處理客戶端消息
func doServerStuff(conn net.Conn) {
nameInfo := make([]byte, 512) //生成一個緩存數組
_, err := conn.Read(nameInfo)
checkError(err)
for {
buf := make([]byte, 512)
_, err := conn.Read(buf) //讀取客戶機發的消息
flag := checkError(err)
if flag == 0 {
break
}
fmt.Println(string(buf)) //打印出來
}
}
//檢查錯誤
func checkError(err error) int {
if err != nil {
if err.Error() == "EOF" {
//fmt.Println("用戶退出了")
return 0
}
log.Fatal("an error!", err.Error())
return -1
}
return 1
}
func main() {
//開啟服務
startServer()
}
以上是服務器的實現,具體看代碼注釋
package main
//客戶機
import (
"bufio"
"fmt"
"log"
"net"
"os"
"strings"
)
//連接服務器
func connectServer() {
//接通
conn, err := net.Dial("tcp", "localhost:7777")
checkError(err)
fmt.Println("連接成功!\n")
//輸入
inputReader := bufio.NewReader(os.Stdin)
fmt.Println("你是誰?")
name, _ := inputReader.ReadString('\n')
//
trimName := strings.Trim(name, "\r\n")
conn.Write([]byte(trimName + " 接入了\n "))
for {
fmt.Println("我們來聊天吧!按quit退出")
//讀一行
input, _ := inputReader.ReadString('\n')
trimInput := strings.Trim(input, "\r\n")
//如果quit就退出
if trimInput == "quit" {
fmt.Println("再見")
conn.Write([]byte(trimName + " 退出了 "))
return
}
//寫出來
_, err = conn.Write([]byte(trimName + " says " + trimInput))
}
}
//檢查錯誤
func checkError(err error) {
if err != nil {
log.Fatal("an error!", err.Error())
}
}
//主函數
func main() {
//連接servser
connectServer()
}
以上是客戶機代碼,具體看注釋
運行的時候,分別go run server和client,你變可以看到這樣就可以連接成功了。
服務器只用開一個,客戶機可以開任意個,並且相互之間沒有干擾。
OK,一個簡單的多線程聊天室就實現了。后期可以加上更多的功能,但無非就是去處理輸入輸出,重點都已經有了。