成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

golang用TCP協(xié)議實現(xiàn)簡單的聊天室-創(chuàng)新互聯(lián)

通常聊天室的架構(gòu)分為服務(wù)器端和客戶端:

成都一家集口碑和實力的網(wǎng)站建設(shè)服務(wù)商,擁有專業(yè)的企業(yè)建站團(tuán)隊和靠譜的建站技術(shù),十多年企業(yè)及個人網(wǎng)站建設(shè)經(jīng)驗 ,為成都上1000+客戶提供網(wǎng)頁設(shè)計制作,網(wǎng)站開發(fā),企業(yè)網(wǎng)站制作建設(shè)等服務(wù),包括成都營銷型網(wǎng)站建設(shè),品牌網(wǎng)站建設(shè),同時也為不同行業(yè)的客戶提供網(wǎng)站設(shè)計、成都網(wǎng)站建設(shè)的服務(wù),包括成都電商型網(wǎng)站制作建設(shè),裝修行業(yè)網(wǎng)站制作建設(shè),傳統(tǒng)機(jī)械行業(yè)網(wǎng)站建設(shè),傳統(tǒng)農(nóng)業(yè)行業(yè)網(wǎng)站制作建設(shè)。在成都做網(wǎng)站,選網(wǎng)站制作建設(shè)服務(wù)商就選成都創(chuàng)新互聯(lián)。

服務(wù)器端:
接受來自于客戶端的連接請求并建立連接;
所有客戶端的連接會放進(jìn)連接池中,用于廣播消息;

客戶端:
連接服務(wù)器;
向服務(wù)器發(fā)送消息;
接收服務(wù)器的廣播消息;

注意事項:
某一個客戶端斷開連接后需要從連接池中摘除,并不再接收廣播消息;
某一個客戶端斷開連接后不能影響服務(wù)器端或別的客戶端的連接;

詳細(xì)的代碼如下,文檔看注釋就好了,不再細(xì)說:

服務(wù)器:

server.go

package main

import (
    "net"
    "log"
    "fmt"
)

func main() {
    port := "9090"
    Start(port)
}

// 啟動服務(wù)器
func Start(port string) {
    host := ":" + port

    // 獲取tcp地址
    tcpAddr, err := net.ResolveTCPAddr("tcp4", host)
    if err != nil {
        log.Printf("resolve tcp addr failed: %v\n", err)
        return
    }

    // 監(jiān)聽
    listener, err := net.ListenTCP("tcp", tcpAddr)
    if err != nil {
        log.Printf("listen tcp port failed: %v\n", err)
        return
    }

    // 建立連接池,用于廣播消息
    conns := make(map[string]net.Conn)

    // 消息通道
    messageChan := make(chan string, 10)

    // 廣播消息
    go BroadMessages(&conns, messageChan)

    // 啟動
    for {
        fmt.Printf("listening port %s ...\n", port)
        conn, err := listener.AcceptTCP()
        if err != nil {
            log.Printf("Accept failed:%v\n", err)
            continue
        }

        // 把每個客戶端連接扔進(jìn)連接池
        conns[conn.RemoteAddr().String()] = conn
        fmt.Println(conns)

        // 處理消息
        go Handler(conn, &conns, messageChan)
    }
}

// 向所有連接上的鄉(xiāng)親們發(fā)廣播
func BroadMessages(conns *map[string]net.Conn, messages chan string) {
    for {

        // 不斷從通道里讀取消息
        msg := <-messages
        fmt.Println(msg)

        // 向所有的鄉(xiāng)親們發(fā)消息
        for key, conn := range *conns {
            fmt.Println("connection is connected from ", key)
            _, err := conn.Write([]byte(msg))
            if err != nil {
                log.Printf("broad message to %s failed: %v\n", key, err)
                delete(*conns, key)
            }
        }
    }
}

// 處理客戶端發(fā)到服務(wù)端的消息,將其扔到通道中
func Handler(conn net.Conn, conns *map[string]net.Conn, messages chan string) {
    fmt.Println("connect from client ", conn.RemoteAddr().String())

    buf := make([]byte, 1024)
    for {
        length, err := conn.Read(buf)
        if err != nil {
            log.Printf("read client message failed:%v\n", err)
            delete(*conns, conn.RemoteAddr().String())
            conn.Close()
            break
        }

        // 把收到的消息寫到通道中
        recvStr := string(buf[0:length])
        messages <- recvStr
    }
}

客戶端:
client.go

package main

import (
    "net"
    "log"
    "fmt"
    "os"
)

func main() {
    Start(os.Args[1])
}

func Start(tcpAddrStr string) {
    tcpAddr, err := net.ResolveTCPAddr("tcp4", tcpAddrStr)
    if err != nil {
        log.Printf("Resolve tcp addr failed: %v\n", err)
        return
    }

    // 向服務(wù)器撥號
    conn, err := net.DialTCP("tcp", nil, tcpAddr)
    if err != nil {
        log.Printf("Dial to server failed: %v\n", err)
        return
    }

    // 向服務(wù)器發(fā)消息
    go SendMsg(conn)

    // 接收來自服務(wù)器端的廣播消息
    buf := make([]byte, 1024)
    for {
        length, err := conn.Read(buf)
        if err != nil {
            log.Printf("recv server msg failed: %v\n", err)
            conn.Close()
            os.Exit(0)
            break
        }

        fmt.Println(string(buf[0:length]))
    }
}

// 向服務(wù)器端發(fā)消息
func SendMsg(conn net.Conn) {
    username := conn.LocalAddr().String()
    for {
        var input string

        // 接收輸入消息,放到input變量中
        fmt.Scanln(&input)

        if input == "/q" || input == "/quit" {
            fmt.Println("Byebye ...")
            conn.Close()
            os.Exit(0)
        }

        // 只處理有內(nèi)容的消息
        if len(input) > 0 {
            msg := username + " say:" + input
            _, err := conn.Write([]byte(msg))
            if err != nil {
                conn.Close()
                break
            }
        }
    }
}

測試方法:

編譯server.go和client.go;
打開終端,啟動server,默認(rèn)會監(jiān)聽9090端口;
再打開多個終端,啟動client,client啟動命令:client 服務(wù)器IP:9090;
在client中輸入字符并回車,可以看到別的終端都會收到消息;

創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國云服務(wù)器,動態(tài)BGP最優(yōu)骨干路由自動選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動現(xiàn)已開啟,新人活動云服務(wù)器買多久送多久。

網(wǎng)頁題目:golang用TCP協(xié)議實現(xiàn)簡單的聊天室-創(chuàng)新互聯(lián)
轉(zhuǎn)載注明:http://jinyejixie.com/article38/dpojsp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動態(tài)網(wǎng)站、App設(shè)計、用戶體驗、網(wǎng)站制作、自適應(yīng)網(wǎng)站、品牌網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司
新和县| 襄城县| 定州市| 当阳市| 韩城市| 波密县| 许昌县| 嵊泗县| 京山县| 桐柏县| 锡林郭勒盟| 南开区| 边坝县| 许昌县| 永靖县| 长岭县| 盐亭县| 吉木萨尔县| 祥云县| 股票| 吉木乃县| 南雄市| 宁强县| 广西| 彰武县| 余江县| 聂荣县| 景谷| 吉林省| 天长市| 祁东县| 惠东县| 双峰县| 诏安县| 邓州市| 长春市| 融水| 盐源县| 罗甸县| 红安县| 宁晋县|