海量用户通讯信息-服务器接收长度|学习笔记

简介: 快速学习海量用户通讯信息-服务器接收长度

开发者学堂课程【Go 语言核心编程 - 面向对象、文件、单元测试、反射、TCP 编程:海量用户通讯信息-服务器接收长度】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/626/detail/9799


海量用户通讯信息-服务器接收长度

 

内容介绍:

一、实现功能-完成用户登录

二、思路分析

 

 

一、实现功能-完成用户登录

要求:

先完成指定用户的验证,用户id=100,密码pwd=123456可以登录,其它用户不能登录。

这里需要先说明Message的组成(示意图),并发送一个Message的流程。

示意图为:

image.png客户端:

1、作用:

(1)、接收的输入的id和pwd

(2)、发送id和密码

(3)、接受到服务端返回的结果

(4)、判断是失败还是成功,并显示对应的页面关键的问题是,怎么组织发送的数据

2、消息类型:

(1)、Message[struct]

------------------

Type string

Data string

(2)、LoginMes str{

userld int

userPed string

}

3、发送流程:

(1)、先创建一个Message的结构体

(2)、mes.Type=登录消息类型

(3)、mes.Data=登录消息的内容(序列)

(4)、对mes进行序列化

5)、在网络传输中,最麻烦丢包

先给服务器发送mes的长度(有多少个字节n)

再发送消息本身

服务器:

1、作用

(1)、接收用户id,pwd【goroutine】

(2)、比较

(3)、返回结果

2、消息类型

(1)、Message[struct]

------------------

Type string

Data string

(2)、LoginMes str{

code int//

error string//

}

序列化

3、接收数据的流程:

(1)、接收到客户端发送的长度.len

(2)、根据接收到的长度len,再接收消息本身

(3)、接收时要判断实际接收到的消息内容是否等于len

(4)、如果不相等,就有接错歇息[后面说]

(5)、取到到-反序列化>Message

(6)、取出message.Data(string)-反序列化>LoginMes

(7)、取出loginMes.useridloginMes.userPwd

(8)、这时就可以比较

(9)、根据比较结果,返回Mess

(10)、发送给客户端

Message实现的功能:

实现完成客户端可以发送消息长度,服务器端可以正常收到该长度值。即先完成客户端到服务器,把发过去的长度前期缩到服务器可以接收到。


二、思路分析:

1、先确定消息Message的格式和结构

示意图:

image.png服务器在main.go在端口8889(可随意设置)进行监听,A客户端(main.go)/login.go/utic.go与端口8899进行数据请求连接,当有一个请求连接,服务器开启一个协程,进行与客户端交互,协程通过端口进行相互通讯

Package common消息包建消息结构体。

2、根据上图的分析完成message代码

新建两个文件夹,第一个是commom文件夹,common下再建一个文件夹专门发布消息。在server下新建main.go文件夹(目前至少需要此文件夹)

message.go下输入代码

package common

const(

LoginnesType       =“LoginMes”

LoginresMesType   =“LoginResMes”//登录返回消息

//确定消息常量

type Message struct.{

Type string ‘json:“type”’//消息类型

Data string ‘json:“data”’//消息的内容

}

//定义两个消息..后面需要再增加(目前需要两种消息,一是登录消息,二是登录返回结果消息)

type LoginMes struct {

UserId int ‘json:“userld”’//用户id

UserPwd string‘json:“userpwd”’ //用户密码

UserName string‘json:“username”’ //用户名

}

type LoginResMes struct {

Code int ‘json:“code”’// 返回状态,500 表示该用户未注册 ,200 表示登录成功

error string‘json:“error”’//返回错误信息

}

注:LoginMes、LoginResMes填充到Data,Type string需要描述消息的具体类型,LomgMes是结构体本身的名字。

下一步是发消息,构建message结构体后进行发送

3、完成main.go代码以及login.go代码

(1)、在main.go输入

package main

import(

"fmt"

"net"

//处理和客户端的通讯

func process(conn net.Conn ){

//读取客户端需要的信息

//提示信息

fmt.Println("服务器在8889端口监听....")

listen, err := net.Listen(itcp","0.0.0.0:8889")

Defer listen.close()

if err != nil {

fmt.Println("net.Listen err=", err)

return

//一旦监听成功,就等待客户端来链接服务器

for {

fmt.Println("等待客户端来链接服务器.....”)

conn,err:=listen.Accept()   (注:conn是服务器与客户端之间相互作用重要的媒介)

If err!=nil{

fmt.println(“listen.Accpt err=”,err)

}

//一旦链接成功,则启动一个协程和客户端保持通讯..

go process (conn)

}

(2)、在login.go输入代码

package main

import.(

"fmt"

“encoding/json”

“encoding/binary”

“net”

“go_code/chatroom/common/message”

)

//写一个函数,完成登录

func login(userId int, userPwd string) (err error) {

//下一个就要开始定协议..

// fmt.Printf(" userId = %d userPwd=%s\n", userId, userPwd)

// return nil

//1.链接到服务器

conn, err := net.Dial("tcp","localhost:8889")

if err != nil {

fmt.Println("net.Dial err=", err)

return

//延时关闭

Defer conn.close

//2.准备通过conn发消息给服务

var mes message.nesssage

Mes.type=message.loginmestype

//3.创建一个LoginMes 结构体

var. loginMes message.LoginMes

loginMes.UserId =userId

loginMes.UserPwd =userPwd

//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) 此时mes既有data又有type。

// 6.将 mes进行序列化化

data, err =json.Marshal(mes)

 if err != nil {

fmt.Println("json.Marshal err=", err)

return

}

// 7.到这个时候 data就是我们要发送的消息

//7.1 先把 data的长度发送给服务器

conn.write(len(data))此方法是错误的。

在go官网查看net包,type Conn中write实际上发送的是byte切片。

// 先获取到 data的长度->转成一个表示长度的byte切片

Package binary

binary包实现了简单的数字与字节序列的转换以及变长值的编解码,其中一个很重要的方法为ByteOrder,被定义的一个方法为putunit32([]byte,unit32),把具体的数字填到unit32,再给byte切片,那么就会把数字转移给byte切片序列。

var pkglen uint32(此处用unit32是因为发送的数据大)

pkgLen=uint32(len(data))

var buf [4]byte  //定义切片

binary.BigEndian.PutUint32(buf[0:4],pkgLen)

// 发送长度

n,err := conn.Write(buf[:4])

if n != 4ll err != nil{

Fmt.println(“conn.write(buf)fail,err”)

Return

}

Fmt.println(“客户端,发送消息的长度ok

return

}

(3)、上述结束后,服务器等待接收,在main.go添加代码

//这里需要延时关闭conn

Defer conn.close()

//循环的读客户端发送的消息

For{

Buf:=make([]byte,8096)

Fmt.println(“读取客户端发送的数据”)

n,err:=conn.read(buf[:4])

if n != 4 ll err != nil {

fmt.Println("conn.Read err=", err)

Return

}

fmt.Println("读到的buf=",buf[:4])

}

func main() {

相关文章
|
1月前
|
存储 弹性计算 运维
ECS信息问题之获取信息如何解决
ECS(Elastic Compute Service,弹性计算服务)是云计算服务提供商提供的一种基础云服务,允许用户在云端获取和配置虚拟服务器。以下是ECS服务使用中的一些常见问题及其解答的合集:
ECS信息问题之获取信息如何解决
|
4天前
|
Java Android开发
Java Socket编程示例:服务器开启在8080端口监听,接收客户端连接并打印消息。
【6月更文挑战第23天】 Java Socket编程示例:服务器开启在8080端口监听,接收客户端连接并打印消息。客户端连接服务器,发送"Hello, Server!"后关闭。注意Android中需避免主线程进行网络操作。
27 4
|
1月前
|
运维 Linux 程序员
最全查看Linux系统状态脚本_linux查询所有服务器信息的脚本,墙都不扶就服你
最全查看Linux系统状态脚本_linux查询所有服务器信息的脚本,墙都不扶就服你
最全查看Linux系统状态脚本_linux查询所有服务器信息的脚本,墙都不扶就服你
|
1月前
|
SQL 存储 数据库
两个Python脚本轻松解决ETL工作:统计多个服务器下所有数据表信息
两个Python脚本轻松解决ETL工作:统计多个服务器下所有数据表信息
|
1月前
|
网络协议 Python
在python中利用TCP协议编写简单网络通信程序,要求服务器端和客户端进行信息互传。 - 蓝易云
在这个示例中,服务器端创建一个socket并监听本地的12345端口。当客户端连接后,服务器发送一条欢迎消息,然后关闭连接。客户端创建一个socket,连接到服务器,接收消息,然后关闭连接。
79 0
|
1月前
|
SQL 存储 数据库
两个Python脚本轻松解决ETL工作:统计多个服务器下所有数据表信息(1)
两个Python脚本轻松解决ETL工作:统计多个服务器下所有数据表信息(1)
|
1月前
|
存储 JSON JavaScript
Node.js 上开发一个 HTTP 服务器,监听某个端口,接收 HTTP POST 请求并处理传入的数据
Node.js 上开发一个 HTTP 服务器,监听某个端口,接收 HTTP POST 请求并处理传入的数据
|
1月前
|
存储 Linux 网络安全
都2023年了还不了解?使用FileZilla搭建信息文件服务器(Windows7)
都2023年了还不了解?使用FileZilla搭建信息文件服务器(Windows7)
|
1月前
|
存储 运维 安全
服务器数据恢复—异常断电导致RAID5阵列信息丢失的数据恢复案例
服务器数据恢复环境: 某品牌ProLiant DL380系列服务器,服务器中有一组由6块SAS硬盘组建的RAID5阵列,WINDOWS SERVER操作系统,作为企业内部文件服务器使用。 服务器故障: 机房供电几次意外中断,服务器出现故障前最后一次异常断电重启后RAID报错,提示无法找到存储设备,进入RAID管理模块做任何操作都死机,重启服务器后问题依旧,用户联系北亚企安数据恢复中心寻求帮助。
|
1月前
|
Linux
查看服务器的配置,系统,cpu等信息
查看服务器的配置,系统,cpu等信息
65 0