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

首頁 > 編程 > Golang > 正文

go語言實現聊天服務器的示例代碼

2020-04-01 18:55:02
字體:
來源:轉載
供稿:網友

看了兩天 go 語言,是時候練練手了。

go 的 routine(例程) 和 chan(通道) 簡直是神器,實現多線程(在 go 里準確的來說是 多例程)簡直不要太輕松。

于是動手碼了一個傻瓜版的黑框聊天器。

server 端:

監聽 TCP 連接;支持自定義客戶端命令;支持消息分發;理論上支持廣播;...

package mainimport (  "fmt"  "net"  "io"  "strconv"  "time"  "strings")const (  NORMAL_MESSAGE = iota  LIST_MESSAGE)var clientSenders = make(map[string] chan string)func send (addr string, conn *net.Conn){  senderChan := clientSenders[addr]  for s := range senderChan{    (*conn).Write([]byte(s))  }}func sendUsersInfo(addr string){  senderChan := clientSenders[addr]  if nil != senderChan{    ls := strconv.Itoa(LIST_MESSAGE)    cs := strconv.Itoa(NORMAL_MESSAGE) + "已登錄客戶端列表:/n"    i := 1    for k := range clientSenders{      a := ""      if k == addr {        a = "(我)"      }      cs = cs + strconv.Itoa(i) + ")" + k + a + "/n"      ls += k + "/n"      i ++    }    cs += "發送消息,可使用 1<-這是給1號客戶端的消息/n(請使用英文以獲取最佳體驗)/n"    senderChan <- cs    time.Sleep(time.Millisecond * 300)    senderChan <- ls    // 發送格式化的列表    fmt.Println("已發送“登錄用戶信息”", addr)  } else{    fmt.Println("客戶端接受通道不存在", addr)  }}func serve (conn *net.Conn){  connect := *conn  addr := connect.RemoteAddr().String()  fmt.Println(addr, "接入服務")  senderChan := make(chan string, 3)  clientSenders[addr] = senderChan  // 啟動發送  go send(addr, conn)  // 發送當前用戶信息  go sendUsersInfo(addr)  buff := make([]byte, 10240)  for {    n, err := connect.Read(buff)    if err != nil {      if err == io.EOF {        fmt.Println("客戶端斷開鏈接,", addr)        delete(clientSenders, addr)        return      } else{        fmt.Println(err)      }    }    msg := string(buff[:n])    // 刷新客戶端列表    if msg == "ls/n" {      go sendUsersInfo(addr)      continue    }    // 提取數據    msgs := strings.Split(msg, "<-")    if len(msg) < 2{      senderChan <- string("數據格式不正確,請聯系開發者")      continue    }    aimAddr := msgs[0]    aimSender := clientSenders[aimAddr]    if aimSender == nil {      senderChan <- string("客戶端已下線,使用 ls 命令獲取最新的客戶端列表")      continue    }    aimSender <- strconv.Itoa(NORMAL_MESSAGE) + "[from:" + addr + "]:" + strings.Join(msgs[1:], "<-")  }}func main(){  addr := ":8080"  listener, err := net.Listen("tcp", addr)  if err != nil{    fmt.Println(err)    return  }  // 啟動消息調度器  defer listener.Close()  // 啟動連接監聽  for {    conn, err := listener.Accept()    if err != nil {      fmt.Println(err)      continue    }    go serve(&conn)  }}

客戶端:

支持斷線重連;支持給特定其他客戶端發信息

package mainimport (  "net"  "fmt"  "io"  "os"  "bufio"  "sync"  "time"  "strings"  "strconv")var conn *net.Connvar addrs []stringconst (  NORMAL_MESSAGE = iota  LIST_MESSAGE)func read(conn2 *net.Conn){  defer func() {    fmt.Println("嘗試重連")    go connectServer()  }()  connect := *conn2  buff := make([]byte, 20140)  for {    n, err := connect.Read(buff)    if err != nil {      if err == io.EOF{        fmt.Println("結束")        (*conn2).Close()        conn = nil        return      } else{        fmt.Println(err)      }    }    msg := string(buff[:n])    t, err := strconv.Atoi(string(msg[0]))    msg = msg[1:]    switch t {    case NORMAL_MESSAGE:      fmt.Print(msg)      break    case LIST_MESSAGE:      // 解析客戶端列表數據      addrs = strings.Split(msg, "/n")      fmt.Println("已接收客戶端列表。/n")      break    default:      fmt.Print(msg)      break    }  }}func connectServer(){  addr := "192.168.99.236:8080"  fmt.Println("等待服務器開啟中")  conn2, err := net.Dial("tcp", addr)  if err != nil {    fmt.Print(err)    fmt.Println("連接失敗,10s后嘗試")    time.Sleep(10 * time.Second)    go connectServer()    return  }  fmt.Println("已連接")  conn = &conn2  go read(&conn2)}func send (){  inputReader := bufio.NewReader(os.Stdout)  for {    input, err := inputReader.ReadString('/n')    if err != nil {      if err == io.EOF{        return      } else{        fmt.Println(err)      }    }    if input == "ls/n" {      (*conn).Write([]byte(input))      continue    }    msgs := strings.Split(input, "<-")    if len(msgs) < 2 {      fmt.Println("發送的姿勢不正確,應該像這樣 1<-給1號發送消息/n")      continue    }    index, err := strconv.Atoi(msgs[0])    if err != nil {      fmt.Println("發送的姿勢不正確,應該像這樣 1<-給1號發送消息/n")      continue    }    if len(addrs) <= index {      fmt.Println("不存在第" + strconv.Itoa(index) + "個客戶端/n")      continue    }    addr := addrs[index-1]    input = addr + "<-" + strings.Join(msgs[1:], "<-")    if nil != conn {      (*conn).Write([]byte(input))    }  }}func main (){  var wg sync.WaitGroup  wg.Add(2)  go connectServer()  go send()  wg.Wait()  defer func() {    if nil != conn {      (*conn).Close()    }  }()}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
色综合久久悠悠| 亚洲自拍偷拍第一页| 懂色av中文一区二区三区天美| 国产成人综合av| 欧美黄色片免费观看| 国产有码在线一区二区视频| 欧美中文在线视频| 欧美大片欧美激情性色a∨久久| 国产一区在线播放| 欧美日韩国产精品一区二区不卡中文| 1769国内精品视频在线播放| 136fldh精品导航福利| 日韩国产高清污视频在线观看| 亚洲国产精品久久| 亚洲精品999| 久久人人爽亚洲精品天堂| 亚洲色无码播放| 亚洲天堂第一页| 性欧美长视频免费观看不卡| 2019中文字幕在线免费观看| 91在线免费看网站| 国产精品女主播视频| 欧美激情亚洲精品| 欧美成人免费在线观看| 色多多国产成人永久免费网站| 欧美日韩国产麻豆| 亚洲国产成人久久综合一区| 2019亚洲日韩新视频| 中文字幕在线观看亚洲| 欧美日韩国产综合新一区| 国产成人啪精品视频免费网| 在线观看视频亚洲| 国产免费一区二区三区香蕉精| 欧美在线观看视频| 欧美与黑人午夜性猛交久久久| 热久久这里只有精品| 亚洲黄一区二区| 国产欧美一区二区三区视频| 亚洲免费一级电影| 欧美性videos高清精品| 欧美日韩一区二区免费在线观看| 欧美成年人视频| 久久精品国产亚洲| 国产精品久久久久99| 最新日韩中文字幕| 欧美日韩色婷婷| 国产主播欧美精品| 国产精品国产三级国产专播精品人| 97精品伊人久久久大香线蕉| 一夜七次郎国产精品亚洲| 亚洲国产精品成人va在线观看| 亚洲自拍偷拍福利| 91国产一区在线| 亚洲国产精久久久久久| 久久久久久免费精品| 日韩精品视频免费专区在线播放| 欧美亚洲在线视频| 亚洲第一区第一页| 欧美国产在线视频| 亚洲一区二区日本| 中文一区二区视频| 欧美另类高清videos| 亚洲理论片在线观看| 在线观看欧美www| 国产精品一区专区欧美日韩| 不卡av日日日| 国产成人精品最新| 精品小视频在线| 亚洲成色777777在线观看影院| 久久99精品视频一区97| 亚洲91精品在线观看| 久久综合国产精品台湾中文娱乐网| 久久这里只有精品视频首页| 欧美在线视频免费| 国产一区二区三区视频在线观看| 亚洲精品美女免费| 亚洲精品久久久久中文字幕欢迎你| 在线播放日韩精品| 97碰碰碰免费色视频| 亚洲日韩中文字幕| 中文字幕亚洲综合久久筱田步美| 日韩高清a**址| 亚洲人成电影网站色www| 国产精品人人做人人爽| 97视频人免费观看| 日韩av中文字幕在线| 2019国产精品自在线拍国产不卡| 深夜福利91大全| 国产精品久久久久久久久久尿| 日韩中文字幕免费| 日韩av影视综合网| 亚洲天堂av电影| 黄色成人在线播放| 日韩在线免费av| 亚洲欧美一区二区三区情侣bbw| 欧美影院久久久| 成人在线视频福利| 久久激情视频久久| 欧美另类69精品久久久久9999| 91欧美精品午夜性色福利在线| 亚洲精品少妇网址| 91超碰中文字幕久久精品| 2019国产精品自在线拍国产不卡| 久久久国产精品一区| 成人乱人伦精品视频在线观看| 久久免费少妇高潮久久精品99| 日韩专区中文字幕| 一区二区三区四区在线观看视频| 日av在线播放中文不卡| 欧美激情视频在线观看| 欧美黑人一级爽快片淫片高清| 亚洲高清久久久久久| 久久免费在线观看| 亚洲午夜久久久久久久| 欧美大片大片在线播放| 91av国产在线| 久久久精品电影| 色无极亚洲影院| 欧美三级免费观看| 精品国产视频在线| 性色av一区二区咪爱| 亚洲综合第一页| 欧美性20hd另类| 成人欧美一区二区三区在线湿哒哒| 精品国产拍在线观看| 日韩最新中文字幕电影免费看| 日韩中文综合网| 亚洲欧美色图片| 另类专区欧美制服同性| 欧美成人亚洲成人| 国产专区精品视频| 亚洲a中文字幕| 秋霞成人午夜鲁丝一区二区三区| 欧美激情图片区| 亚洲精品久久久久国产| 精品国产1区2区| 蜜臀久久99精品久久久久久宅男| 亚洲精品国产美女| 岛国av一区二区在线在线观看| 欧美在线视频观看| 亚洲美腿欧美激情另类| www.xxxx精品| 日本亚洲欧美成人| 伊人伊成久久人综合网小说| 日韩国产高清污视频在线观看| 欧美性生活大片免费观看网址| 欧美成人精品在线视频| 亚洲第一福利视频| 国产精品亚洲自拍| 亚洲一区二区三区在线免费观看| 欧美日韩国产区| 亚洲精品动漫100p| 激情成人中文字幕| 久久免费视频网| 欧美在线视频观看| 国模私拍一区二区三区| 夜夜嗨av色一区二区不卡| 亚洲国产欧美久久| 国产视频精品免费播放| 综合国产在线视频| 亚洲精品日韩在线| 色偷偷av亚洲男人的天堂| 日韩电影免费在线观看中文字幕| 日韩亚洲一区二区|