亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Golang > 正文

Golang實現的聊天程序服務端和客戶端代碼分享

2020-04-01 19:24:07
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了Golang實現的聊天程序服務端和客戶端代碼分享,本文先是講解了實現邏輯,然后給出了實現代碼,需要的朋友可以參考下
 

實現邏輯

1、Golang 版本  1.3

2、實現原理:

  1、主進程建立TCP監聽服務,并且初始化一個變量 talkChan := make(map[int]chan string)

  2、當主進程ACCEPT連接請求后,利用go 啟動一個協程A去維持和客戶端的連接,把taokChan帶入到協程里

  3、和客戶端建立連接的協程A,發送消息給客戶端,使其發送自己的用戶信息。

  4、協程A在收到客戶端發送的用戶信息后,建立一個此用戶對應的管道 talkChan[uid] = make(chan string)

  5、協程A再啟動一個協程A1去專門用來讀取客戶端發送的消息,并且用來判斷是發送給誰的消息,然后把消息放到對應的chan里。

  6、協程A再啟動一個協程A2用來讀取此用戶對應的管道,如果里面有信息,則取出來發送到客戶端。

實現代碼

服務端測試代碼:server.go

 

復制代碼代碼如下:

package main

 

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

func handleConnection(conn net.Conn, talkChan map[int]chan string) {
    //fmt.Printf("%p/n", talkChan)  //用以檢查是否是傳過來的指針

    /*
        定義當前用戶的uid
    */
    var curUid int

    var err error

    /*
        定義關閉通道
    */
    var closed = make(chan bool)

    defer func() {
        fmt.Println("defer do : conn closed")
        conn.Close()
        fmt.Printf("delete userid [%v] from talkChan", curUid)
        delete(talkChan, curUid)
    }()

    /**
     * 提示用戶設置自己的uid, 如果沒設置,則不朝下執行
     */
    for {
        //提示客戶端設置用戶id
        _, err = conn.Write([]byte("請設置用戶uid"))
        if err != nil {
            return
        }
        data := make([]byte, 1024)
        c, err := conn.Read(data)
        if err != nil {
            //closed <- true  //這樣會阻塞 | 后面取closed的for循環,沒有執行到。
            return
        }
        sUid := string(data[0:c])

        //轉成int類型
        uid, _ := strconv.Atoi(sUid)
        if uid < 1 {
            continue
        }
        curUid = uid
        talkChan[uid] = make(chan string)
        //fmt.Println(conn, "have set uid ", uid, "can talk")

        _, err = conn.Write([]byte("have set uid "+sUid+" can talk"))
        if err != nil {
            return
        }
        break
    }

    fmt.Println("err 3")

    //當前所有的連接
    fmt.Println(talkChan)

    //讀取客戶端傳過來的數據
    go func() {
        for {
            //不停的讀客戶端傳過來的數據
            data := make([]byte, 1024)
            c, err := conn.Read(data)
            if err != nil {
                fmt.Println("have no client write", err)
                closed <- true //這里可以使用 | 因為是用用的go 新開的線程去處理的。 |  即便chan阻塞,后面的也會執行去讀 closed 這個chan
            }

            clientString := string(data[0:c])

            //將客戶端過來的數據,寫到相應的chan里
            if curUid == 3 {
                talkChan[4] <- clientString
            } else {
                talkChan[3] <- clientString
            }

        }
    }()

    /*
        從chan 里讀出給這個客戶端的數據 然后寫到該客戶端里
    */
    go func() {
        for {
            talkString := <-talkChan[curUid]
            _, err = conn.Write([]byte(talkString))
            if err != nil {
                closed <- true
            }
        }
    }()

    /*
       檢查是否已經關閉連接 如果關閉則推出該線程  去執行defer語句
    */
    for {
        if <-closed {
            return
        }
    }
}

func main() {

    /**
    建立監聽鏈接
    */
    ln, err := net.Listen("tcp", "127.0.0.1:6010")
    if err != nil {
        panic(err)
    }

    //創建一個管道

    //talkChan := map[f]
    talkChan := make(map[int]chan string)

    fmt.Printf("%p/n", talkChan)

    /*
       監聽是否有客戶端過來的連接請求
    */
    for {
        fmt.Println("wait connect...")
        conn, err := ln.Accept()
        if err != nil {
            log.Fatal("get client connection error: ", err)
        }

        go handleConnection(conn, talkChan)
    }
}

 

客戶端測試代碼:client.go

 

復制代碼代碼如下:

package main

 

import (
    "fmt"
    "math/rand"
    "net"
)

func main() {
    conn, err := net.Dial("tcp", "127.0.0.1:6010")
    if err != nil {
        panic(err)
    }

    fmt.Fprintf(conn, "hello server/n")

    defer conn.Close()
    go writeFromServer(conn)

    for {
        var talkContent string
        fmt.Scanln(&talkContent)

        if len(talkContent) > 0 {
            _, err = conn.Write([]byte(talkContent))
            if err != nil {
                fmt.Println("write to server error")
                return
            }
        }
    }
}

func connect() {
    conn, err := net.Dial("tcp", "127.0.0.1:6010")
    if err != nil {
        panic(err)
    }

    fmt.Fprintf(conn, "hello server/n")

    defer conn.Close()
    go writeFromServer(conn)

    for {
        var talkContent string
        fmt.Scanln(&talkContent)

        if len(talkContent) > 0 {
            _, err = conn.Write([]byte(talkContent))
            if err != nil {
                fmt.Println("write to server error")
                return
            }
        }
    }
}

func writeFromServer(conn net.Conn) {
    defer conn.Close()
    for {
        data := make([]byte, 1024)
        c, err := conn.Read(data)
        if err != nil {
            fmt.Println("rand", rand.Intn(10), "have no server write", err)
            return
        }
        fmt.Println(string(data[0:c]) + "/n ")
    }
}

 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91牛牛免费视频| 亚洲精品久久7777777| 国产69精品久久久久久| 狠狠躁18三区二区一区| 亚洲精品电影在线观看| 97国产在线观看| 亚洲福利视频二区| 国产极品jizzhd欧美| 久久精品一本久久99精品| 欧美成人四级hd版| 久久久精品影院| 国产精品视频男人的天堂| 久久国产精品亚洲| 亚洲精品一区二区在线| 日韩av电影国产| 成人有码在线视频| 国产国语videosex另类| 日韩欧美亚洲范冰冰与中字| 美女啪啪无遮挡免费久久网站| 欧美日韩一区二区免费在线观看| 日韩精品欧美国产精品忘忧草| 亚洲人成在线电影| 欧美成年人视频网站欧美| 欧美日韩中文字幕日韩欧美| 国产精品444| 欧美怡红院视频一区二区三区| 久久久免费在线观看| 欧美一级片免费在线| 久久综合久久美利坚合众国| 国内精品久久久久久| 7777kkkk成人观看| 亚洲精品456在线播放狼人| 亚洲精品丝袜日韩| 一夜七次郎国产精品亚洲| 亚洲自拍偷拍在线| 亚洲free性xxxx护士白浆| 狠狠色狠狠色综合日日五| 最好看的2019的中文字幕视频| 精品日本高清在线播放| 日韩一级裸体免费视频| 国产精品精品视频一区二区三区| 97精品国产91久久久久久| 北条麻妃一区二区在线观看| 国产精品免费观看在线| 国产精品视频久久久| 国产在线视频一区| 亚洲精品一区二区三区婷婷月| 欧美俄罗斯性视频| 欧美精品一区二区三区国产精品| 久久久久久有精品国产| 国产精品尤物福利片在线观看| 91最新国产视频| 91精品国产高清久久久久久| 国产91在线播放精品91| 国内精品久久久久影院优| 亚洲性夜色噜噜噜7777| 日韩一区二区av| 欧美高跟鞋交xxxxxhd| 美女福利精品视频| 国产精品影院在线观看| 在线日韩中文字幕| 日韩黄在线观看| 国产69精品久久久久9999| 亚洲精品视频网上网址在线观看| 日韩中文字幕在线视频播放| 欧美大码xxxx| 欧美日韩国产一中文字不卡| 精品亚洲aⅴ在线观看| 精品女厕一区二区三区| 亚洲美女精品久久| 欧美日韩久久久久| 国产精品久久久久久久久免费看| 国产综合在线视频| 亚洲在线第一页| 在线免费看av不卡| 青草青草久热精品视频在线观看| 亚洲男人第一网站| 欧美丰满片xxx777| 亚洲色图日韩av| 久久久久久香蕉网| 亚洲第一中文字幕| 中文字幕国产精品| 97福利一区二区| 97在线精品国自产拍中文| 久久躁日日躁aaaaxxxx| 欧美一级黄色网| 欧美激情视频网| 精品成人av一区| 欧美www在线| 丝袜情趣国产精品| 亚洲欧美精品在线| 亚洲free性xxxx护士白浆| 亚洲欧美日韩天堂一区二区| 午夜精品久久久久久久99热浪潮| 亚洲肉体裸体xxxx137| 精品视频中文字幕| 国产精品第一页在线| 亚洲天堂男人天堂女人天堂| 亚洲a∨日韩av高清在线观看| 97超级碰碰人国产在线观看| 久久夜色精品亚洲噜噜国产mv| 伊人亚洲福利一区二区三区| 久久精品国产清自在天天线| 精品人伦一区二区三区蜜桃网站| 亚洲色图综合网| 国产精品福利在线观看| 国产丝袜一区视频在线观看| 国产精品美女999| 久久精品中文字幕一区| 成人免费淫片视频软件| 日韩在线观看免费全| 成人在线小视频| 久久久久久亚洲精品不卡| 国产精品自产拍在线观看中文| 色青青草原桃花久久综合| 日本成人激情视频| 欧美在线一区二区三区四| 亚洲va欧美va国产综合久久| 欧美激情视频在线观看| 欧美大片在线影院| 亚洲精品91美女久久久久久久| 国产高清在线不卡| 欧美第一黄网免费网站| 懂色av一区二区三区| 欧美精品在线视频观看| 在线色欧美三级视频| 欧美激情xxxx性bbbb| 在线免费观看羞羞视频一区二区| 欧美午夜精品在线| 97精品国产97久久久久久春色| 欧美黄色片视频| 欧美亚洲成人网| 精品久久香蕉国产线看观看亚洲| 欧美怡春院一区二区三区| 92福利视频午夜1000合集在线观看| 亚洲一区二区三区乱码aⅴ蜜桃女| 国语自产偷拍精品视频偷| 亚洲国产天堂久久国产91| 91九色国产在线| 国产精品日韩在线观看| 一个人www欧美| 久久伊人精品视频| 成人日韩av在线| 日韩精品视频在线| 精品国产美女在线| 中文国产成人精品久久一| 国产精品白丝av嫩草影院| 成人有码视频在线播放| 午夜精品久久久久久久99黑人| 欧美一级视频一区二区| 欧美午夜丰满在线18影院| 国产美女高潮久久白浆| 欧美黑人巨大精品一区二区| 色樱桃影院亚洲精品影院| y97精品国产97久久久久久| 亚洲精品按摩视频| 久久精品国产99国产精品澳门| 亚洲新中文字幕| 亚洲自拍av在线| 91久久久久久久久久| 97人人爽人人喊人人模波多| 一本色道久久88精品综合| 免费99精品国产自在在线| 欧美性猛交xxxx乱大交极品|