go實現的簡易TCP的客戶端和服務器


今天介紹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,一個簡單的多線程聊天室就實現了。后期可以加上更多的功能,但無非就是去處理輸入輸出,重點都已經有了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM