1.定义消息类型
package Common
const (
LoginMesType = "LoginMes"
LoginResType = "LoginResMes"
)
type Message struct {
Type string `json:"type"` //消息类型
Data string `json:"data"` //消息内容
}
type LoginMes struct {
UserId int `json:"userid"`
UserPwd string `json:"userpwd"`
UserName string `json:"username"`
}
type LoginResMes struct {
Code int `json:"code"`
Error string `json:"error"`
}
2.完成服务器端代码功能
package main
import (
"fmt"
"net"
)
func process(conn net.Conn){
fmt.Println("读取客户端发送的连接");
defer conn.Close();//这里需要延时关闭,如果不过关闭奇怪情况
buf:=make([]byte,8096);
for {
fmt.Println("等待读取发送的数据");
n,err:=conn.Read(buf[0:4]);
if n != 4 || err != nil {
fmt.Println("conn is error");
return;
}
fmt.Println("read length buf=",buf[:4]);
}
}
func main(){
fmt.Println("服务器在8889端口监听....");
listen,err:= net.Listen("tcp","0.0.0.0:8889");
if err !=nil {
fmt.Printf("net.Listen is error");
}
for {
fmt.Println("等待客户端的连接");
conn,err := listen.Accept();
if err != nil {
fmt.Println("listen accept is err");
}
go process(conn);
}
}
3.完成客户端代码书写
package main
import "fmt"
var userId int;
var userPwd string;
func main(){
var key int;
var loop=true;
for loop {
fmt.Println("----------------------欢迎多人聊天系统----------------------");
fmt.Println("\t\t\t 1:登录聊天室");
fmt.Println("\t\t\t 2:注册用户");
fmt.Println("\t\t\t 3:退出系统");
fmt.Println("\t\t\t 请选择(1-3):");
fmt.Scanf("%d\n",&key);
switch key {
case 1:
fmt.Println("登录聊天系统页面");
loop=false;
case 2:
fmt.Println("注册用户页面");
loop=false;
case 3:
fmt.Println("退出系统");
loop=false;
default:
fmt.Println("你的输入有误,请重新输入");
}
}
if key == 1 {
fmt.Println("请输入用户ID:");
fmt.Scanf("%d\n",&userId);
fmt.Println("请输入用户密码:");
fmt.Scanf("%s\n",&userPwd);
login(userId,userPwd);
}
}
package main import ( Common "common" "encoding/binary" "encoding/json" "fmt" "net" ) func login(userId int,userPwd string) (err error) { fmt.Printf("登录学生ID为%v 密码为%v",userId,userPwd); //连接远程服务器 conn,err:=net.Dial("tcp","localhost:8889"); if err != nil { fmt.Println("net.Dial is error"); } defer conn.Close(); var msg Common.Message; //1.设置消息类型 msg.Type=Common.LoginMesType;//设置登录结构体类型 //2.创建消息结构体 var logMes Common.LoginMes; logMes.UserId=userId; logMes.UserName=userPwd; data,err:= json.Marshal(logMes);//将消息内容序列化但是data是切片 if err != nil { fmt.Println("json.Marshal is error"); return; } msg.Data=string(data); //3.将全部消息序列化 data,err = json.Marshal(msg);//这是切片 if err != nil { fmt.Println("json.Marshal is error"); return; } //讨论如何发送 pkgLen:= uint32(len(data)); var bytes [4]byte; binary.BigEndian.PutUint32(bytes[0:4],pkgLen);//这个是重点需要将数据长度转换为字节序列 n,err:=conn.Write(bytes[0:4]); if n != 4 || err != nil { fmt.Println("send is error"); return; } fmt.Println("mess length is success"); return; }
原文:https://www.cnblogs.com/zh718594493/p/14220277.html