利用GO语言实现多人聊天室实例教程
程序员文章站
2022-03-18 18:09:20
前言
运用go里面的net包中的相关方法来实现一个基于tcp的简单多人聊天室,用一个服务器来管理,主要反馈客户端是否连接成功并显示客户端输入的内容,并且发送给每一个在服务...
前言
运用go里面的net包中的相关方法来实现一个基于tcp的简单多人聊天室,用一个服务器来管理,主要反馈客户端是否连接成功并显示客户端输入的内容,并且发送给每一个在服务器上连接的客服端,下面话不多说了,来一起看看详细的介绍吧。
示例代码
服务器代码
// server package main import ( "fmt" "net" ) var connmap map[string]*net.tcpconn func checkerr(err error) int { if err != nil { if err.error() == "eof" { fmt.println("用户退出") return 0 } fmt.println("发生错误") return -1 } return 1 } func say(tcpconn *net.tcpconn) { for { data := make([]byte, 256) total, err := tcpconn.read(data) if err != nil { fmt.println(string(data[:total]), err) } else { fmt.println(string(data[:total])) } flag := checkerr(err) if flag == 0 { break } for _, conn := range connmap { if conn.remoteaddr().string() == tcpconn.remoteaddr().string() { continue } conn.write(data[:total]) } } } func main() { //var conn net.tcpconn //localaddr :=conn.localaddr().string() //fmt.println(localaddr) //tcpaddr, _ := net.resolvetcpaddr("tcp",localaddr) tcpaddr, _ := net.resolvetcpaddr("tcp", "192.168.128.216:8080") tcplisten, _ := net.listentcp("tcp", tcpaddr) connmap = make(map[string]*net.tcpconn) for { tcpconn, _ := tcplisten.accepttcp() defer tcpconn.close() connmap[tcpconn.remoteaddr().string()] = tcpconn fmt.println("连接客户端信息:", tcpconn.remoteaddr().string()) go say(tcpconn) } }
本来打算用系统的localaddr()
函数来直接调用本地网络地址,但是这里调用一直报格式的错误,所以这里用本地地址直接输在里面,端口是8080//192.168.247.128:8080,也可以改成和客户端相似的代码来进行调用,但鉴于服务器唯一,所以就不做更改了
客户端代码
// client package main import ( "fmt" "net" "os" ) var ch chan int = make(chan int) var nickname string func reader(conn *net.tcpconn) { buff := make([]byte, 256) for { j, err := conn.read(buff) if err != nil { ch <- 1 break } fmt.printf("%s\n", buff[0:j]) } } func main() { if len(os.args) != 2 { fmt.fprintf(os.stderr, "usage:%s host:port", os.args[0]) os.exit(1) } service := os.args[1] tcpadd, _ := net.resolvetcpaddr("tcp", service) //tcpadd, _ := net.resolvetcpaddr("tcp", "localhost:8080") conn, err := net.dialtcp("tcp", nil, tcpadd) if err != nil { fmt.println("服务没打开") os.exit(1) } defer conn.close() go reader(conn) fmt.println("请输入昵称") fmt.scanln(&nickname) fmt.println("你的昵称是:", nickname) //var str string for { var msg string fmt.scan(&msg) fmt.print("<" + nickname + ">" + "说:") //for i, _ := range msg { // fmt.printf("%c", msg[i]) //} fmt.println(msg) b := []byte("<" + nickname + ">" + "说:" + msg) conn.write(b) select { case <-ch: fmt.println("server发生错误,请重新连接") os.exit(2) default: } } }
客户端主要就是向服务器发起连接,然后发送和接收数据,原计划定义一个字符切片来存储读来的数据,但是出现了调用fmt.println()来输出是时候显示ascii码的错误,所以改成直接往一个空字符串里面读写,然后再来调用fmt.println()
,显示出正确的字符串
运行服务器
go build server.go
./server
或 go run server.go
运行客户端
go build client.go
./client 服务器地址:端口(上面例子是192.168.247.128:8080)
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。
下一篇: 拍婚纱照怎么摆姿势好看?拍婚纱照姿势大全