Golang实现简单tcp服务器03 -- 文本广播式聊天服务器/客户端
2015-06-02 00:00
666 查看
用Golang实现 文本广播式聊天服务器/客户端
本节, 我们将一步一步的把上一节完成的echo服务器/客户端改造成一个文本信息的聊天室服务端的改动
服务器为了实现聊天信息的群体广播, 需要记录所有连接到服务器的客户端信息, 所以, 我们需要添加一个集合来保存所有客户端的连接:
var ConnMap map[string]*net.TCPConn
接着, 每次当有新的客户端连接到服务器时, 需要把这个客户端连接行信息加入集合:
ConnMap[tcpConn.RemoteAddr().String()] = tcpConn
当服务器收到客户端的聊天信息时, 需要广播到所有客户端, 所以我们需要利用上面保存TCPConn的map来遍历所有TCPConn进行广播, 用以下方法实现:
func boradcastMessage(message string) { b := []byte(message) for _, conn := range ConnMap { conn.Write(b) } }
客户端代码改动
客户端代码改动相对简单, 只是加入了用户自己输入聊天信息的功能, 在连接成功并且 启动了消息接收的gorountine后, 加入以下代码:
for { var msg string fmt.Scanln(&msg) if msg == "quit" { break } b := []byte(msg + "\n") conn.Write(b) }
完整的服务端代码如下:
server.go
package main import ( "bufio" "fmt" "net" ) // 用来记录所有的客户端连接 var ConnMap map[string]*net.TCPConn func main() { var tcpAddr *net.TCPAddr ConnMap = make(map[string]*net.TCPConn) tcpAddr, _ = net.ResolveTCPAddr("tcp", "127.0.0.1:9999") tcpListener, _ := net.ListenTCP("tcp", tcpAddr) defer tcpListener.Close() for { tcpConn, err := tcpListener.AcceptTCP() if err != nil { continue } fmt.Println("A client connected : " + tcpConn.RemoteAddr().String()) // 新连接加入map ConnMap[tcpConn.RemoteAddr().String()] = tcpConn go tcpPipe(tcpConn) } } func tcpPipe(conn *net.TCPConn) { ipStr := conn.RemoteAddr().String() defer func() { fmt.Println("disconnected :" + ipStr) conn.Close() }() reader := bufio.NewReader(conn) for { message, err := reader.ReadString('\n') if err != nil { return } fmt.Println(conn.RemoteAddr().String() + ":" + string(message)) // 这里返回消息改为了广播 boradcastMessage(conn.RemoteAddr().String() + ":" + string(message)) } } func boradcastMessage(message string) { b := []byte(message) // 遍历所有客户端并发送消息 for _, conn := range ConnMap { conn.Write(b) } }
客户端完整代码如下:
client.go
package main import ( "bufio" "fmt" "net" ) func main() { var tcpAddr *net.TCPAddr tcpAddr, _ = net.ResolveTCPAddr("tcp", "127.0.0.1:9999") conn, _ := net.DialTCP("tcp", nil, tcpAddr) defer conn.Close() fmt.Println("connected!") go onMessageRecived(conn) // 控制台聊天功能加入 for { var msg string fmt.Scanln(&msg) if msg == "quit" { break } b := []byte(msg + "\n") conn.Write(b) } } func onMessageRecived(conn *net.TCPConn) { reader := bufio.NewReader(conn) for { msg, err := reader.ReadString('\n') fmt.Println(msg) if err != nil { quitSemaphore <- true break } } }
最后分别编译server与client试试效果吧!
go build server.go
go build client.go
先启动server端, 然后新开两个个终端, 启动客户端, 在其中一个客户端里键入聊天信息后回车, 会发现另外一个客户端收到了刚刚发送的聊下天信息
完事大吉!
相关源码:
https://git.oschina.net/victoriest/go-simple-tcp-server.git
相关文章推荐
- Go语言将支持Android
- Golang实现的聊天程序服务端和客户端代码分享
- Go语言入门教程之Arrays、Slices、Maps、Range操作简明总结
- GO语言异常处理机制panic和recover分析
- go语言执行windows下命令行的方法
- Go语言计算两个经度和纬度之间距离的方法
- Go语言排序与接口实例分析
- Go语言导出内容到Excel的方法
- go语言实现sqrt的方法
- Go语言MessageBox用法实例
- Go语言判断指定文件是否存在的方法
- go语言制作的zip压缩程序
- go语言channel实现多核并行化运行的方法
- Go语言MD5加密用法实例
- go语言使用scp的方法实例分析
- Go语言中的switch用法实例分析
- Golang学习笔记(三):控制流
- go语言检测文件是否存在的方法
- Go语言里的结构体文法实例分析
- Go语言结构体定义和使用方法