用go语言实现一个server作中转群发消息,多个客户端聊天
1)服务器开启,等待来自客户端的连接,把每一个客户端存储在map中
2)客户端连接服务器,给自己取一个别名,存储在服务器
3)服务器群发消息,通知在线的客户端有新的加入
4)客户端发消息,服务器解析协议,群发给每一个客户端
5)客户端下线
server
// server project main.go
package main
import (
"fmt"
"net"
"strings"
)
var ConnMap map[string]net.Conn = make(map[string]net.Conn)
//ConnMap := make(map[string]net.Conn)
func main() {
listen_socket, err := net.Listen("tcp", "127.0.0.1:8000")
if err != nil {
fmt.Println("server start error")
}
defer listen_socket.Close()
fmt.Println("server is wating ....")
for {
conn, err := listen_socket.Accept()
if err != nil {
fmt.Println("conn fail ...")
}
fmt.Println(conn.RemoteAddr(), "connect successed")
go handle(conn)
}
}
func handle(conn net.Conn) {
for {
data := make([]byte, 255)
msg_read, err := conn.Read(data)
if msg_read == 0 || err != nil {
continue
}
//解析协议
msg_str := strings.Split(string(data[0:msg_read]), "|")
switch msg_str[0] {
case "nick":
fmt.Println(conn.RemoteAddr(), "-->", msg_str[1])
for k, v := range ConnMap {
if k != msg_str[1] {
v.Write([]byte("[" + msg_str[1] + "]: join..."))
}
}
ConnMap[msg_str[1]] = conn
case "say":
for k, v := range ConnMap {
if k != msg_str[1] {
fmt.Println("Send "+msg_str[2]+" to ", k)
v.Write([]byte("[" + msg_str[1] + "]: " + msg_str[2]))
}
}
case "quit":
for k, v := range ConnMap {
if k != msg_str[1] {
v.Write([]byte("[" + msg_str[1] + "]: quit"))
}
}
delete(ConnMap, msg_str[1])
}
}
}
client
// client project main.go
package main
import (
"fmt"
"net"
)
var nick string = ""
func main() {
conn, err := net.Dial("tcp", "127.0.0.1:8000")
if err != nil {
fmt.Println("conn fail...")
}
defer conn.Close()
fmt.Println("connect server successed \n")
//给自己取一个昵称吧
fmt.Printf("Make a nickname:")
fmt.Scanf("%s", &nick)
fmt.Println("hello : ", nick)
conn.Write([]byte("nick|" + nick))
go Handle(conn)
var msg string
for {
msg = ""
fmt.Scan(&msg)
conn.Write([]byte("say|" + nick + "|" + msg))
if msg == "quit" {
conn.Write([]byte("quit|" + nick))
break
}
}
}
func Handle(conn net.Conn) {
for {
data := make([]byte, 255)
msg_read, err := conn.Read(data)
if msg_read == 0 || err != nil {
break
}
fmt.Println(string(data[0:msg_read]))
}
}
程序截图
不同语言间的通信: https://blog.csdn.net/dyd961121/article/details/81355147