• go实现聊天系统(二)


    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("			 1:登录聊天室");
    		fmt.Println("			 2:注册用户");
    		fmt.Println("			 3:退出系统");
    		fmt.Println("			 请选择(1-3):");
    		fmt.Scanf("%d
    ",&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
    ",&userId);
    		fmt.Println("请输入用户密码:");
    		fmt.Scanf("%s
    ",&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;
    }
  • 相关阅读:
    ubuntu18.04英文环境解决各种软件中文乱码问题
    Centos6两个镜像文件的合并方法
    将centos的yum源修改为阿里云的yum源
    Linux TOP 命令总结
    Nginx add SSL 证书 基础配置
    Nginx Http 核心模块中Server Location 配置
    df -h执行卡住不动问题解决
    Jetty Session Persistence By Redis
    Spring @Transactional配置知识梳理
    通用FTP Client模块设计与实现
  • 原文地址:https://www.cnblogs.com/zh718594493/p/14220277.html
Copyright © 2020-2023  润新知