UnitySocket框架应用//粘包分包的理解//阻塞与非阻塞的自我理解/音游Demo描述

本文详细介绍了UnitySocket框架的应用,包括如何处理同步通信时的多线程优化,以及如何实现异步Socket通信。通过NetMsgObject类解析消息,实现了客户端(Client)和服务端(Server)的发送和接收功能。音游场景中,服务端支持多人连接,处理不同用户的音乐和灯光效果。此外,文章还讨论了黏包、分包的处理策略,以及阻塞与非阻塞的概念。最后,展示了客户端和服务器端的代码示例。
摘要由CSDN通过智能技术生成

Socket框架
Socket通信使用同步时 若有多个客户端同时连接服务端 每次都开启一条线程来接收客户端的消息并返回结果 显然消耗过大 所有有必要进行优化 可以采用多线程(接收线程 发送线程 其他处理线程)和异步Socket 使用异步Socket时 封装CommonSocket 无论服务端或者客户端都可用的通用Socket; NetMsgObject类用来处理消息的解析 将一条完整的消息解析为消息头+消息尾 消息头用来辨别不同消息处理 封装返回NetMsgObject类型的数据便于消息处理 封装Client客户端(Init(实例Socket 绑定ip和端口)Connect(BeginConnect开始连接)SendMsg(假发送 只是把数据压到了发送队列中)UpdateSendMsg真正将数据发送BeginSend RecvMsg(将接收到从服务端返回的消息压入接收队列中)UpdateRecvMsg真正将数据取出BeginReceive);封装Server服务端(Init(实例Socket 绑定ip和端口)Accept(开始接受客户端的连接BeginAccept)UpdateRecvFromClient(实时接收客户端数据)UpdateSendToClient(广播给所有客户端))音游 服务端支持多人连接 根据用户操作播放不同音乐及闪光灯效 用户输入不互斥音效可组合 停止操作时灯灭音乐停止 客户端输入使用NetWorkStream的BeginWrite和BeginRead写入和读取 基于客户端的不同输入 服务端根据消息类型作出处理 执行相应操作(随机灯光的颜色 开启线程睡眠0.1s实现缓变的效果)获取AudioSource组件的clip属性加载音效 Play方法播放音效 黏包 当客户端发送的数据量小时将多条完整或不完整的消息合并 黏在一次发送给服务端 服务端收到了一整段数据(多条消息)所以在接收端定义NetMsgObject(定义int值记录消息长度(4+Head+Body) Head消息头为辨别消息的消息类型用short表示占2字节 Body消息尾)Receive接收到客户端发来黏包数据的总长度Length 首先判断Length是否小于6 如果小于6(消息长度+消息头)说明接收到残包 压入队列 等待下次接收到完数据处理;如果大于6则转为NetMsgObject取到消息长度len 如果len<Length总长度 则接收字节数组中从0到len是完整的一条消息可做处理 处理下条消息时从第一条消息长度的len-1开始解析
分包 当客户端发送的数据量大时将消息分割为几部分 多次发送给服务端 服务端不止接收一次状态同步 相较于帧同步误差大 基于客户端的输入向服务端发送消息后客户端完成自走逻辑 服务端接收到消息后 每隔固定时间发送确认包(确认当前服务端上该角色具体正确的属性和位置);当服务端返回消息时 客户端有可能只接受不处理 客户端移动结束后 这时服务端会发送强制包到客户端 强制包中有服务端中存储该角色的属性和位置 通过对比数据 如果在设定的允许范围内 客户端不做改变;如果不一致则强制保持一致(平滑移动或强制位移)阻塞与非阻塞(Blocking&Non-Blocking)
客户端与服务端为例 服务端等待客户端发来的一条新的消息 但是服务端关闭了客户端Socket 服务端却一直在等待客户端的消息 此时服务端线程阻塞 因为服务端的accept方法一直在等待新消息的到来 阻塞卡住时的两种情况 发送时(Send)比如你要按下某键才发送消息时 只有要发送的数据传到了Send函数中 才会继续向下执行;接收时(Recv) 接收一方将数据放到缓存区(byte[])中 只有收到数据放入缓存区后 才会向下执行;解决阻塞:同步+多线程(异步)
非阻塞:服务端仍在接收客户端的消息(RecvCallBack) 但无论发来新消息还是没发来(空消息)都立刻返回 不会一直将线程挂在接收函数的调用上 异步非阻塞解决了阻塞的问题 所以Socket(Client/Server结构)多用异步非阻塞
同步与异步(Sync&Async)
同步与异步和阻塞与非阻塞相互联系但又不等同 同步有可能导致阻塞 异步解决阻塞 同步异步主要针对client(同步是死等结果;异步是有结果了通知我)阻塞非阻塞主要针对Server(阻塞是被调用时没数据不返回;非阻塞是被调用不管如何立即返回) ///CLientusing System;
using System.Text;
usi

Unity实现Socket通讯时,常常会遇到TCP粘包和拆包的问题。下面我将介绍在Unity如何解决这些问题。 TCP粘包是指在传输过程,由于数据缓冲区的限制,多个小的数据包可能会被合并成一个大的数据包,导致数据的解析和处理出现问题。为了解决这个问题,可以通过以下两种方式来处理。 第一种方式是定长包头+包体的设计。即在数据包前面添加一个固定长度的包头,包头包含了包体的长度信息。接收方在接收数据时,首先读取包头的长度信息,然后再根据长度信息读取相应长度的数据进行解析和处理。 第二种方式是使用特殊的字符序列作为包的分隔符。例如,在每个数据包的末尾添加一个换行符或其他不常用的字符作为分隔符。接收方在接收数据时,通过查找这个分隔符来确定包的结束位置,然后对数据进行解析和处理。 TCP拆包是指在传输过程,一个大的数据包可能会被拆分成多个小的数据包,导致数据的解析和处理出现问题。为了解决这个问题,可以通过以下方式来处理。 可以在接收方使用缓冲区来接收数据,并且设置一个最大接收长度。当接收到的数据长度小于最大接收长度时,将数据放入缓冲区,并在缓冲区进行数据的拼接。当接收到的数据长度大于等于最大接收长度时,对缓冲区的数据进行解析和处理,并清空缓冲区。 以上是Unity实现Socket通讯时解决TCP粘包和拆包问题的方法。希望对你有帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值