golang簡易版聊天室

功能需求:tcp

建立一個聊天室,實現羣聊和單聊的功能,直接輸入爲羣聊,@某人後輸入爲單聊spa

效果圖:code

羣聊:blog

 

單聊:string

 

服務端:it

package main

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

type info struct {
    conn net.Conn
    name string
}

var ch_all chan string = make(chan string)
var ch_one chan string = make(chan string)
var ch_who chan string = make(chan string)
var infos map[string]info = make(map[string]info)

func handle(conn net.Conn) {
    defer conn.Close()

    buf := make([]byte, 100)
    n, _ := conn.Read(buf)
    name := string(buf[:n])
    var oneinfo info
    oneinfo.conn = conn
    oneinfo.name = name
    addr := conn.RemoteAddr().String()
    infos[addr] = oneinfo
    msg := name + "進入聊天室"
    ch_all <- msg

    for {
        n, _ := conn.Read(buf)
        if n == 0 {
            fmt.Printf("%s斷開鏈接\n", addr)
            msg = name + "離開聊天室"
            delete(infos, addr)
            ch_all <- msg
            fmt.Println(msg)
            return
        }
        if string(buf[:n])[0] == '@' {
            sli := strings.Fields(string(buf[1:n])) //隔開
            who := sli[0]
            msg = strings.Join(sli[1:], "") //後邊的再拼接回去
            ch_who <- who
            ch_one <- name + "->me : " + msg //單發
            continue
        }
        ch_all <- name + "->all : " + string(buf[:n]) //羣發
    }
}

func sendone() {
    for {
        who := <-ch_who
        msg := <-ch_one
        for _, v := range infos {
            if v.name == who {
                v.conn.Write([]byte(msg))
                break
            }
        }
    }
}
func sendall() {
    for {
        msg := <-ch_all
        for _, val := range infos {
            val.conn.Write([]byte(msg))
        }
    }
}
func main() {
    listener, _ := net.Listen("tcp", ":9009")
    defer listener.Close()
    go sendall()
    go sendone()
    for {
        conn, _ := listener.Accept()
        fmt.Printf("%s創建鏈接\n", conn.RemoteAddr().String())
        go handle(conn)
    }
}

客戶端:io

package main

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

func scandata(conn net.Conn) {
    for {
        //設置能夠讀取帶空格的myscan
        myscan := bufio.NewReader(os.Stdin)
        buf, _, _ := myscan.ReadLine()
        if string(buf) == "q" {
            os.Exit(0)
        }
        conn.Write(buf)
    }
}
func main() {
    conn, _ := net.Dial("tcp", "127.0.0.1:9009")
    buf := make([]byte, 1024)
    args := os.Args
    conn.Write([]byte(args[1]))
    go scandata(conn)
    for {
        n, _ := conn.Read(buf)
        fmt.Println(string(buf[:n]))
    }
}
相關文章
相關標籤/搜索