一.概述
- 点对点通信就是客户端A发送消息给服务端,再由服务端把消息传递给客户端B.相同道理客户端B想给客户端A发送消息也需要把消息传递给服务端,再由服务端把消息传递给A
- 正常情况下客户端A和客户端B可以通过用户名、IP等唯一身份标识区分每个用户.在本功能练习中要求客户端先注册用户名,然后告诉服务端给谁发消息.如果用户名存在不允许注册
在本功能练习中用户信息存储到临时容器map中,没有进行持久化操作.
二.代码实现
项目结构如下
--项目名--src--clientclient.go--serverserver.gomain.go
在server.go中编写代码 ```go package main
import ( “net” “fmt” “strings” )
type User struct { Username string OtherUsername string Msg string ServerMsg string }
var ( userMap = make(map[string]net.Conn) user = new(User) )
func main() { addr, := net.ResolveTCPAddr(“tcp4”, “:9999”) lis, := net.ListenTCP(“tcp4”, addr)
for {conn, _ := lis.Accept()go func() {for {b := make([]byte, 512)//读取数据count, _ := conn.Read(b)arrStr := strings.Split(string(b[:count]), "-")user.Username = arrStr[0]user.OtherUsername = arrStr[1]user.Msg = arrStr[2]user.ServerMsg = arrStr[3]userMap[user.Username] = connif v, ok := userMap[user.OtherUsername]; ok && v != nil {user.ServerMsg = ""n, e := v.Write([]byte(fmt.Sprintf("%s-%s-%s-%s", user.Username, user.OtherUsername, user.Msg, user.ServerMsg)))if n == 0 || e != nil {conn.Close()delete(userMap, user.OtherUsername)break}} else {user.ServerMsg = "对方不在线"n, e := conn.Write([]byte(fmt.Sprintf("%s-%s-%s-%s", user.Username, user.OtherUsername, user.Msg, user.ServerMsg)))}}}()}
}
- 在client.go中编写代码```gopackage mainimport ("net""fmt""sync""os""strings")type User struct {Username stringOtherUsername stringMsg stringServerMsg string}var (user = new(User)wg sync.WaitGroup)func main() {wg.Add(1)fmt.Println("请登录,输入用户名:")fmt.Scanln(&user.Username)fmt.Println("请输入要给谁发送消息")fmt.Scanln(&user.OtherUsername)addr, _ := net.ResolveTCPAddr("tcp4", ":9999")conn, _ := net.DialTCP("tcp4", nil, addr)go func() {fmt.Print("请输入:(只提示一次,以后直接输入即可)")for {fmt.Scanln(&user.Msg)if user.Msg == "exit" {conn.Close()wg.Done()os.Exit(0)}conn.Write([]byte(fmt.Sprintf("%s-%s-%s-%s", user.Username, user.OtherUsername, user.Msg, user.ServerMsg)))}}()go func() {for {rb := make([]byte, 512)c, _ := conn.Read(rb)user2 := new(User)arrStr := strings.Split(string(rb[:c]), "-")user2.Username = arrStr[0]user2.OtherUsername = arrStr[1]user2.Msg = arrStr[2]user2.ServerMsg = arrStr[3]if user2.ServerMsg != "" {fmt.Println("\t\t\t服务器消息:", user2.ServerMsg)} else {fmt.Println("\t\t\t", user2.Username, ":", user2.Msg)}}}()wg.Wait()}
