欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

利用GO语言实现多人聊天室实例教程

程序员文章站 2022-06-18 08:49:04
前言 运用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)

利用GO语言实现多人聊天室实例教程

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。