1. 程式人生 > >2.22 網路通訊4:TCP廣播

2.22 網路通訊4:TCP廣播

服務端實現

import (
    "fmt"
    "net"
        "os"
    "strings"
)

//儲存客戶端連線, key,ip埠,value 連結物件
var onlineConnsMap = make(map[string]net.Conn)

//訊息佇列,緩衝區
var messageQueue = make(chan string, 1000)

//訊息,處理程式退出
var quitchan = make(chan bool)

func CheckErrorS(err error) {
    if err != nil {
        fmt.Println("網路錯誤"
, err.Error()) os.Exit(1) } } func Processinfo(conn net.Conn) { buf := make([]byte, 1024) //開創緩衝區 defer func() { //關閉連線 conn.Close() fmt.Println("連線已關閉:",conn.RemoteAddr()) }() for { n, err := conn.Read(buf) //讀取資料 if err != nil { fmt.Println("讀取客戶端訊息出錯,err="
,err) break } if n != 0 { //訊息處理, message := string(buf[0:n]) fmt.Printf("受到客戶端%v訊息:%s\n",conn.RemoteAddr(),message) //訊息佇列儲存訊息 messageQueue <- message fmt.Println("該條訊息已加入佇列...") }else{ fmt.Println("讀取客戶端訊息長度為0"
) } } } //訊息的協程 func consumeMessage() { for { select { case message := <-messageQueue: //取出訊息 fmt.Println("已從佇列中取出訊息") strs := strings.Split(message, "#") //字串切割 if len(strs) > 1 { //127.0.0.1:12345#去死 //擷取地址並裁減頭尾空白 addr := strs[0] addr = strings.TrimSpace(addr) //擷取內容 msg := strs[1] //給所有客戶端群發此訊息 /*for addr, conn := range onlineConnsMap { //迴圈線上列表 _, err := conn.Write([]byte(msg)) fmt.Println("伺服器傳送訊息", msg, "給", addr) if err != nil { fmt.Println("線上連結傳送失敗") } }*/ //@某人,發訊息 if conn, ok := onlineConnsMap[addr]; ok { _, err := conn.Write([]byte(msg)) fmt.Println("伺服器傳送訊息", msg) if err != nil { fmt.Println("線上連結傳送失敗") } } } case <-quitchan: //處理退出 os.Exit(0) } } } func main() { //建立TCP伺服器 listener, err := net.Listen("tcp", "127.0.0.1:8898") CheckErrorS(err) defer listener.Close() //關閉網路 fmt.Println("伺服器正在等待") go consumeMessage() for { conn, err := listener.Accept() //新的客戶端連線 CheckErrorS(err) //處理每一個客戶端 addr := fmt.Sprint(conn.RemoteAddr()) //取出地址 onlineConnsMap[addr] = conn fmt.Println("客戶端列表") fmt.Println("-------------------") for key := range onlineConnsMap { //迴圈每一個連結 fmt.Println(key) } go Processinfo(conn) } }

客戶端呢實現

import (
    "fmt"
    "net"
    "bufio"
    "os"
)

func CheckErrorC(err error) {
    if err != nil {
        fmt.Println("網路錯誤", err.Error())
    }
}

func MessageSend(conn net.Conn) {
    var input string
    for {
        reader := bufio.NewReader(os.Stdin) //讀取鍵盤輸入
        data, _, _ := reader.ReadLine()     //讀取一行
        input = string(data)                //鍵盤輸入轉化為字串

        if input == "exit" {
            conn.Close()
            fmt.Println("客戶端關閉")
            break
        }

        _, err := conn.Write([]byte(input)) //輸入寫入字串
        fmt.Println("傳送訊息", input)
        if err != nil {
            conn.Close()
            fmt.Println("客戶端關閉")
            break
        }

    }
}

func main() {
    conn, err := net.Dial("tcp", "127.0.0.1:8898") //建立TCP伺服器
    defer conn.Close()                             //延遲關閉網路連線
    CheckErrorC(err)                               //檢查錯誤

    go MessageSend(conn)                           //開啟一個協程,處理髮送
    //conn.Write([]byte("hello  nimei"))

    //協程,負責收取訊息
    buf := make([]byte, 1024)
    for {
        numOfBytes, err := conn.Read(buf)
        CheckErrorC(err)
        fmt.Println("收到伺服器訊息", string(buf[:numOfBytes]))
    }

    fmt.Println("客戶端關閉")

}