海量用户通讯系统-服务器接收消息2|学习笔记

简介: 快速学习海量用户通讯系统-服务器接收消息2

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

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


海量用户通讯系统-服务器接收消息2

 

一、反复出现readPkg的原因及解决方法

1、反复出现readPkg的原因:

因为message.go的server这个地方是一直在进for循环的读取,读取包包,读的是-err =conn.Read(buf[:4])这个地方,读的时候它阻塞这个的前提是对方也就是conn一直是有效的,就是大家都持有的一个连接,才会在这里阻塞。也就是conn没有关闭的情况下,才会阻塞。如果说任意一方,不论是客户端还是服务端有一方关闭这个连接,这个就会立即停止。同理如果客户端关闭了conn则,不会阻塞。若不会堵塞就会出现刚才的情况,反复的打出”读取客户端发送的数据...

readPkg err= read pkg header error

Mes= < >”

反复打出这段话的原因是如果不堵塞就读不到东西,读不到东西就报一个错误,又return到下面这里

mes, err := readPkg(conn)

if err != nil {

fmt.PrintIn(“readPkg err=”err)

}

return到这个错误后,又说readPkg err,然后没有进行任何处理,又去进行读取,又返回到上面这个地方,结果发现又读不到东西,把错误抛出,又返回下面那处,就造成了这种现象。

2、解决反复出现现象的方法:

当以下这个代码读的时候

mes, err := readPkg(conn)

if err != nil {

fmt.PrintIn(“readPkg err=”err)

}

已经读错了,有两个方案。一个是双方均退出,就可以做一个判断。判断的方法是

mes, err := readPkg(conn)

if err != nil {

if err == io.EOF

fmt.PrintIn(“客户端退出,服务器端也正常退出“)

return

}     else {

fmt.PrintIn(“readPkg err=”err)

return

}

fmt.PrintIn(“mes=”,mes)

这种判断分两种情况一种是服务端退出了,一种是其他情况,这两种方法均能保证代码没问题。这两个均做完后,EOF那里的原因是没有导io包。将io包导入,如下

package main

import(

“fmt”

“net”

“go_code/chatroom/common/message”

“encoding/binary”

“encoding/json”

“errors’

“io”

将io包导入后,在客户端login这处也先暂时不休眠。休眠测试已经完成了,休眠20秒后会自动关掉,接着测试一下。首先将server端编译一下,然后客户端在编译一下,接着启动一下server端,在启动conn端,接着看效果,假设输入100,密码是tom,接着运行,效果如图

image.png由观察可得它在读取当中,因为现在不进行发送也没有退出,相对于卡在了read那个地方,因为连接都还持有,没有将其关闭,所以这个架构20秒就会关闭。20秒后的提示信息是”readPkg err= read pkg header error”,但是没有将信息打出来。那么这个错误便还不是那个错误,那么证明刚刚的分析还存在一定问题。接着重复刚才的操作,再进行一次,更改原来的代码,如下

package main

import(

“fmt”

“net”

“go_code/chatroom/common/message”

“encoding/binary”

“encoding/json”

—“errors’

“io”

接着在使其运行一次,输入100,密码abc,再次运行观察结果。与原猜想相同,出现了客户端退出,服务器端也退出的提示信息。

3、代码实现

Client/login.go做了修改

//发送了消息本身

-,err = conn.write(data)

if err != nil {

fmt.PrintIn(“conn.write(data) fail”, err)

return

}

//休眠20

time.Sleep(20 * time.Second)

fmt.PrintIn(“休眠了20..”)

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

}

server/main.go

修改//处理客户端的通讯

func process(conn net.conn)

//这里需要延时关闭conn

defer conn.Close()

//循环的客户端发送的信息

for {

//这里我们将数据包,直接封装一个函数readPkg,返回Message, Err

mes,err := readPkg(conn)

if err != nil {

if err == io.EOF {

fmt.PrintIn(“客户端退出,服务器端也退出”)

return

} else

fmt.PrintIn(“readPkg err=”, err)

return

}

}

fmt.PrintIn(“mes=”, mes)

}

}

将读取包的任务封装到了一个函数中readPkg()

func readPkg(conn net.Conn) (mes message.Message, err error) {

buf := make([]byte,8096)

fmt.PrintIn(“读取客户端发送的数据...“)

//conn.Read 在conn没有被关的情况下,才会阻塞

//如果客户端关闭了conn则,就不会阻塞

-,err = conn.Read(buf[:4])

if err != nil {

//err = errors.New(“read pkg header error”)

return

}

//根据buf[:4]转成一个uint32类型

var pkgLen uint32

pkgLen = binary.BigEndian.Uint32(buf[0:4])

//根据pkgLen该消息内容

n, err := conn.Read(buf[:pkgLen])

if n != int(pkgLen) | | err != nil {

//err =errrors.New(“read pkg body errror”)

Return

}

//把pkgLen反序列化成-> message.Message

//技术就是一层窗户纸 &mes

err = json.Unmarshal(buf[:pkgLen], &mes)

if err != nil {

fmt.PrintIn(“json.Unmarsha err”, err)

return

}

return

}

相关文章
|
4天前
|
Java Android开发
Java Socket编程示例:服务器开启在8080端口监听,接收客户端连接并打印消息。
【6月更文挑战第23天】 Java Socket编程示例:服务器开启在8080端口监听,接收客户端连接并打印消息。客户端连接服务器,发送&quot;Hello, Server!&quot;后关闭。注意Android中需避免主线程进行网络操作。
27 4
|
1月前
|
运维 Linux 程序员
最全查看Linux系统状态脚本_linux查询所有服务器信息的脚本,墙都不扶就服你
最全查看Linux系统状态脚本_linux查询所有服务器信息的脚本,墙都不扶就服你
最全查看Linux系统状态脚本_linux查询所有服务器信息的脚本,墙都不扶就服你
|
10天前
|
弹性计算 监控 Linux
云服务器 ECS产品使用问题之在使用yum安装PHP相关的包时遇到问题,因为系统中找不到php-mysql和php-imap这两个包,该怎么办
云服务器ECS(Elastic Compute Service)是各大云服务商阿里云提供的一种基础云计算服务,它允许用户租用云端计算资源来部署和运行各种应用程序。以下是一个关于如何使用ECS产品的综合指南。
|
1月前
|
弹性计算 监控 安全
【阿里云弹性计算】ECS实例监控与告警系统构建:利用阿里云监控服务保障稳定性
【5月更文挑战第23天】在数字化时代,阿里云弹性计算服务(ECS)为业务连续性提供保障。通过阿里云监控服务,用户可实时监控ECS实例的CPU、内存、磁盘I/O和网络流量等指标。启用监控,创建自定义视图集中显示关键指标,并设置告警规则(如CPU使用率超80%),结合多种通知方式确保及时响应。定期维护和优化告警策略,利用健康诊断工具,能提升服务高可用性和稳定性,确保云服务的卓越性能。
67 1
|
23天前
|
Ubuntu 网络协议 Linux
ubuntu linux 系统搭建我的世界基岩版 私服我的世界服务器
ubuntu linux 系统搭建我的世界基岩版 私服我的世界服务器
44 0
|
1月前
|
运维 监控 Linux
提升系统稳定性:Linux服务器性能监控与故障排查实践深入理解与实践:持续集成在软件测试中的应用
【5月更文挑战第27天】在互联网服务日益增长的今天,保障Linux服务器的性能和稳定性对于企业运维至关重要。本文将详细探讨Linux服务器性能监控的工具选择、故障排查流程以及优化策略,旨在帮助运维人员快速定位问题并提升系统的整体运行效率。通过实际案例分析,我们将展示如何利用系统资源监控、日志分析和性能调优等手段,有效预防和解决服务器性能瓶颈。
|
1月前
|
弹性计算 监控 数据库
【阿里云弹性计算】企业级应用上云实战:基于阿里云 ECS 的 ERP 系统迁移案例
【5月更文挑战第25天】制造企业将面临资源不足、维护成本高和数据安全问题的ERP系统迁移到阿里云ECS,实现业务上云。通过数据迁移、应用部署、网络配置和性能优化等步骤,企业享受到弹性计算资源、高可靠性和数据安全优势,降低维护成本。阿里云提供24小时支持,助力企业数字化转型。此案例展示企业级应用上云的可行性,鼓励更多企业借助云计算实现创新发展。
47 0
|
1月前
|
存储 前端开发 Linux
在 SAP ABAP 系统里访问 FTP 服务器
在 SAP ABAP 系统里访问 FTP 服务器
|
6天前
|
存储 弹性计算 Linux
阿里云账号注册、完成实名认证、试用云服务器和购买云服务器流程参考
本文为大家介绍新手用户从注册阿里云账号,完成实名认证,然后试用云服务器和购买云服务器的主要流程,适合初次购买和试用阿里云服务器的新手用户参考。
阿里云账号注册、完成实名认证、试用云服务器和购买云服务器流程参考
|
3天前
|
弹性计算 运维 安全
阿里云ecs使用体验
整了台服务器部署项目上线