golang简易版聊天室

功能需求:

创建一个聊天室,实现群聊和单聊的功能,直接输入为群聊,@某人后输入为单聊

效果图:

群聊:

 

单聊:

服务端:

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断开连接
", 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建立连接
", conn.RemoteAddr().String())
        go handle(conn)
    }
}

客户端:

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]))
    }
}
原文地址:https://www.cnblogs.com/lesroad/p/10051105.html