一.概述
- 点对点通信就是客户端A发送消息给服务端,再由服务端把消息传递给客户端B.相同道理客户端B想给客户端A发送消息也需要把消息传递给服务端,再由服务端把消息传递给A
- 正常情况下客户端A和客户端B可以通过用户名、IP等唯一身份标识区分每个用户.在本功能练习中要求客户端先注册用户名,然后告诉服务端给谁发消息.如果用户名存在不允许注册
在本功能练习中用户信息存储到临时容器map中,没有进行持久化操作.
二.代码实现
项目结构如下
--项目名
--src
--client
client.go
--server
server.go
main.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] = conn
if 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中编写代码
```go
package main
import (
"net"
"fmt"
"sync"
"os"
"strings"
)
type User struct {
Username string
OtherUsername string
Msg string
ServerMsg 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()
}