golang实现聊天室(五)
完成服务端广播消息
server
package mainimport ("fmt""log""math/rand""net"
)type Client_list struct {list map[net.Conn]string
}func main() {client_list := Client_list{make(map[net.Conn]string, 0)}var conn, err = net.Listen("tcp","127.0.0.1:6888")if err != nil {return}for {c, err := conn.Accept()if err != nil {return}go client_list.Receive(c)}
}//noinspection GoUnresolvedReference
func (client_list *Client_list) Receive(c net.Conn) {for {reveive_byte := make([]byte, 256)lens, err := c.Read(reveive_byte)if err != nil {log.Fatal("Receive error")}reveive_byte = reveive_byte[:lens]fmt.Printf("%s\n", reveive_byte)client_list.BroadMessage(c)}
}func (client_list *Client_list) BroadMessage(c net.Conn) {// 用户信息唯一表,唯一标识码user := rand.Int() % 2client_list.list[c] = string(user)// 遍历map表for clientKey, _ := range client_list.list{if clientKey == c {continue}var _, err = clientKey.Write([]byte("服务器广播消息"))if err != nil {log.Fatal("Wrong about abroad message")}}}
client1
package mainimport ("fmt""log""net""time"
)func main() {var conn, err = net.DialTimeout("tcp", "127.0.0.1:6888", 30*time.Second)if err != nil {log.Fatal("conn error")}for {conn.Write([]byte("user 2\n "))time.Sleep(5 * time.Second)re_message := make([]byte, 255)length, err := conn.Read(re_message)if err != nil {return}re_message = re_message[:length]fmt.Printf("%s\n", re_message)}conn.Close()
}
client2
package mainimport ("fmt""log""net""time"
)func main() {var conn, err = net.DialTimeout("tcp", "127.0.0.1:6888", 30*time.Second)if err != nil {log.Fatal("conn error")}for {conn.Write([]byte("user 2\n "))time.Sleep(5 * time.Second)re_message := make([]byte, 255)length, err := conn.Read(re_message)if err != nil {return}re_message = re_message[:length]fmt.Printf("%s\n", re_message)}conn.Close()
}
小结
- 完成了服务端客户端通信的基本模型
- 客户端建立连接,服务端存储客户端基本信息
- 服务端根据map信息广播消息
下期目标
- 指定用户名作为唯一信息map
- 从命令行接收发送信息
- 服务端广播唯一客户端发送的信息,给除这个客户端以外的客户端信息
- 当客户端退出时,服务端监测,并从map删除,广播消息给其他客户端
- 客户端可使用加密算法,对发送信息加密再发送