文章目录
BufferEntity 通信协议的细节规定
USocket 初始化发送报文的接口
UdpClient 网络报文的处理
1.USocket目的:提供socket发送的接口,以及socket接受的业务
1)修改
public static UClient local; //客户端代理,主要做的是完成发送的逻辑和处理的逻辑,保证报文的顺序
2)初始USocket完善,增加客户端代理
//提供初始化接口,写个构造函数就可以了
public USocket(Action<BufferEntity> dispatchNetEvent)
{
//参数为0表示系统自动分配
udpClient = new UdpClient(0);
server = new IPEndPoint(IPAddress.Parse(ip), port);
//初始化要调用一下UClient对象,
//dispatchNetEvent为处理消息分发的行数,传递过去
UClient local = new UClient(this, server, 0, 0, 0, dispatchNetEvent);
}
2.客户端代理
1)构造函数初始化
public UClient(USocket uSocket,IPEndPoint endPoint,int sendSN,int handlSN,int sessionID, Action dispatchNetEvent)
2)处理消息(待完善)
没写,待完善
3)发送报文的接口
public void Send(BufferEntity package)
4)超时重传检测接口(待完善)
public async void CheckOutTime()
3.代码
using System.Net;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;
namespace Game.Net
{
//客户端的代理
public class UClient
{
//参数
public IPEndPoint endPoint;
USocket uSocket; //USocket内部封装了发送的接口
public int sessionID; //会话ID,客户端只需要接受报文的会话ID赋值就行了
//服务端要拿到不同的会话ID区分不同的客户端
public int sendSN = 0; //发送序号
public int handleSN = 0; //处理的序号,为了保证报文的顺序性
//这里为什么要当作形参来传递呢?
//为了应对以后的业务扩展
Action<BufferEntity> handleAction; //定义处理报文的函数,实际就是分发报文给各个游戏模块
//先来个构造函数->完成初始化
//sendSN 发送的序号
//handlSN 处理的序号
//sessionID 会话ID
//Action<BufferEntity> dispatchNetEvent 派发报文的事件传递进来,也就是待处理的消息
public UClient(USocket uSocket,IPEndPoint endPoint,int sendSN,int handlSN,int sessionID, Action<BufferEntity> dispatchNetEvent)
{
this.uSocket = uSocket;
this.endPoint = endPoint;
this.sendSN = sendSN;
this.handleSN = handleSN;
this.sessionID = sessionID;
handleAction = dispatchNetEvent;
}
//处理消息
//定义字典存缓存,int是序号,值是BufferEntity,使用线程安全的字典
ConcurrentDictionary<int, BufferEntity> sendPackage = new ConcurrentDictionary<int, BufferEntiy>();
//发送报文的接口
//这里不需要在void前加async,因为在下面的send已经实现了
public void Send(BufferEntity package)
{
//更新报文发送的时间
package.time = 0; //暂时先等于0
sendSN += 1;
package.sn = sendSN;
package.Encoder(false); //对package编码,传递false表示不是ACK的报文
if (sessionID != 0) //等于0表示还没跟服务器建立连接
{
//缓存起来,因为可能需要重发(缓存需要定义一个字典)
sendPackage.TrtAdd(sendSN, package);
}
else
{
//还没跟服务器建立连接,所以不需要j进行缓存
}
uSocket.Send(package.buffer, endPoint); //客户端的endPoint没啥用,还可以再优化下
}
//定义超时的时间
int overtime = 150;
//超时重传检测的接口
//需要定期从字典里面取出报文,然后判断是否超时就可以了
public async void CheckOutTime()
{
await Tash.Delay(overtime);
foreach (var package in sendPackage.Values)
{
}
}
}
}