修改客户端

先画出程序框架图【思路】,再写代码

步骤1


改后的框架图
程序框架
package main

import (
    "awesomeProject/chatroom/client/process"
    "fmt"

)

//一个表示用户id 一个表示用户密码
var usrId int
var usrpwd string

func main()  {
    //接收用户的选择
    var key int
    //判断是否继续显示菜单
    //var loop = true

    for  true{
        fmt.Println("-----------------欢迎登录多人聊天系统---------------")
        fmt.Println("\t\t\t\t 1 登录聊天室")
        fmt.Println("\t\t\t\t 2 注册用户")
        fmt.Println("\t\t\t\t 3 退出系统")
        fmt.Println("\t\t\t\t 请选择(1-3):")


        fmt.Scanf("%d\n",&key)
        switch key {
        case 1:
            fmt.Println("登录聊天室")
            //loop = false
            fmt.Println("请用户输入自己的ID")
            fmt.Scanf("%d\n",&usrId)
            fmt.Println("请用户输入自己的密码")
            fmt.Scanf("%s\n",&usrpwd)
            //先把登录的函数  写到另外一个文件中  login.go
            //这里我们需要从新调用

            //完成登录  创建一个UserProcess的实例
            up := &process.UserProcess{}
            up.Login(usrId,usrpwd)
        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",&usrId)
    //  fmt.Println("请用户输入自己的密码")
    //  fmt.Scanf("%s\n",&usrpwd)
    //  //先把登录的函数  写到另外一个文件中  login.go
    //  //这里我们需要从新调用
    //
    //  login(usrId,usrpwd)
    //  //if err!=nil {
    //  //  fmt.Println("登录失败")
    //  //}else {
    //  //  fmt.Println("登录成功")
    //  //}
    //}else if key == 2{
    //  fmt.Println("进行用户注册")
    //}

}

client/main.go

package process

import (
    "awesomeProject/chatroom/client/utils"
    "fmt"
    "net"
    "os"
)

func ShowMenu()  {
    fmt.Println("-------恭喜***登录成功---------")
    fmt.Println("-------1 显示在线用户列表---------")
    fmt.Println("-------2 发送消息---------")
    fmt.Println("-------3 退出系统---------")
    fmt.Println("请选择1-4")
    var key int
    fmt.Scanf("%d\n",&key)
    switch key {
    case 1:
        fmt.Println("显示在线用户列表")
    case 2:
        fmt.Println("发送消息")
    case 3:
        fmt.Println("查看信息列表")
    case 4:
        fmt.Println("你选择退出了系统")
        os.Exit(0)
    default:
        fmt.Println("你输入的选项不对")
    }
    

}

//和服务器端保持通讯

func serverProcessMes(conn net.Conn)  {
    //创建一个Transfer  实例  不停的读取服务器发送的消息

    tf := &utils.Transfer{
        Conn: conn,
    }
    for  {
        fmt.Println("客户端正在等待服务器发送的消息")
        mes,err := tf.ReadPkg()
        if err != nil{
            fmt.Println("read err=",err)
            return
        }
        //如果读取到消息
        fmt.Println(mes)
    }
}

client/process/server.go

package process

import (
    "awesomeProject/chatroom/client/utils"
    "awesomeProject/chatroom/common/message"
    "encoding/binary"
    "encoding/json"
    "fmt"
    "net"
)

type UserProcess struct {
    //暂时不需要字段。。。。

}


//给关联一个用户登录的方法


func (this *UserProcess)Login(usrId int,usrpwd string)(err error)  {
    ////下一步要开始定协议
    //fmt.Printf("userId= %d   usrpwd=%s\n",usrId,usrpwd)
    //return nil
    conn,err := net.Dial("tcp","localhost:8889")
    if err!=nil{
        fmt.Println("net Dail err=",err)
        return
    }
    //延时关闭
    defer conn.Close()

    //2 通过conn发送消息给服务
    var mes message.Message
    mes.Type = message.LoginMesType
    //3 创建一个LoginMes 结构体
    var LoginMes message.LoginMes
    LoginMes.UserId = usrId
    LoginMes.UserPwd = usrpwd
    //4 将loginMes 序列化
    data,err := json.Marshal(LoginMes)
    if err!=nil{
        fmt.Println("json marshal err=",err)
        return
    }
    //5  把data赋给  mes.data 字段
    mes.Data = string(data)

    // 6 将mes 进行序列化

    data,err = json.Marshal(mes)
    if err!= nil{
        fmt.Println("json marshal err=",err)
        return
    }
    //7 这个时候data 就是我们要发送的数据
    //7.1  先把data的长度发送给服务器
    // 先获得到 data的长度-》转成一个表示长度的byte切片
    var pkgLen uint32
    pkgLen = uint32(len(data))
    var buf [4]byte
    binary.BigEndian.PutUint32(buf[0:4],pkgLen)
    //发送长度
    n,err := conn.Write(buf[:4])
    if err!=nil||n != 4 {
        fmt.Println("conn write err=",err)
        return
    }
    fmt.Printf("客户端,发送消息长度ok  有%d 字节 %s",len(data),string(data))

    // 发送消息本身
    _,err = conn.Write(data)
    if err != nil{
        fmt.Println("conn write err=",err)
        return
    }

    //这里还需要处理服务器端返回的消息

    //创建一个Transfer 实例
    tf := &utils.Transfer{
        Conn: conn,
    }
    mes,err = tf.ReadPkg()

    if err != nil{
        fmt.Println("readpkg err=",err)
        return
    }


    //将mes的data部分反序列化为 LoginResMes
    var loginResMes message.LoginResMes
    err = json.Unmarshal([]byte(mes.Data),&loginResMes)
    if loginResMes.Code == 200 {
        fmt.Println("用户登录成功")
        //这里我们还需要启动一个协程
        //该协程保持和服务器通讯  如果服务器有数据推送给客户端
        //则接收并显示在客户端的终端
        go serverProcessMes(conn)

        // 1 显示登录成功的菜单  循环
        for  {
            ShowMenu()
        }
    }else if loginResMes.Code == 500{
        fmt.Println(loginResMes.Error)
    }
    return
}

client/process/userProcess.go

package utils

import (
    "awesomeProject/chatroom/common/message"
    "encoding/binary"
    "encoding/json"
    "fmt"
    "net"
)


//这里将这些方法关联到结构体中
type Transfer struct {
    //分析应该有哪些字段
    Conn net.Conn
    Buf [8096]byte  //  这是传输时使用的缓存
}

func (this *Transfer)ReadPkg()(mes message.Message,err error)  {
    //buf := make([]byte,8096)

    fmt.Println("等待客户端发送的数据")
    // conn read 在conn没有被关闭的情况下,才会阻塞
    //如果客户端关闭了 conn 就不会阻塞了
    _,err = this.Conn.Read(this.Buf[:4])
    if err != nil{
        fmt.Println("conn read err=",err)
        return
    }
    // 根据读到的buf长度 转换为uint32 的类型
    var pkgLen uint32
    pkgLen = binary.BigEndian.Uint32(this.Buf[0:4])
    // 根据pkgLen 读取消息内容
    n,err := this.Conn.Read(this.Buf[:pkgLen])
    if n != int(pkgLen) || err != nil{
        fmt.Println("conn read err=",err)
        return
    }
    //pkgLen 反序列化成_>message.Message 的类型
    err = json.Unmarshal(this.Buf[:pkgLen],&mes)
    if err != nil{
        fmt.Println("json err=",err)
        return
    }
    return
}

func (this *Transfer)WritePkg(data []byte)(err error)  {
    //先发送一个长度给对方
    var pkgLen uint32
    pkgLen = uint32(len(data))
    //var buf [4]byte
    binary.BigEndian.PutUint32(this.Buf[0:4],pkgLen)
    //发送长度
    n,err := this.Conn.Write(this.Buf[:4])
    if err!=nil||n != 4 {
        fmt.Println("conn write err=",err)
        return
    }
    //发送data 本身
    n,err = this.Conn.Write(data)
    if n != int(pkgLen)||err !=nil{
        fmt.Println("conn write er=",err)
        return
    }
    return
}

client/utils/utils.go

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容