1.背景回顾介绍
1.上6回只是设计了通信报文的设计的类
2.这次是写封装网络端口的类
2.主要函数介绍
1)接受报文+创建一个队列接受数据
public async void ReceiveTask()
2)发送报文
public async void Send(byte[] data,IPEndPoint endPoint)
3)发送ACK报文
public async void SendACK(BufferEntity bufferEntity)
4)关闭udp的接口
public void Close()
5)初始化接口
public USocket(Action dispatchNetEvent)
3.代码
using System.Net;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net.Sockets;
using UnityEngine;
using System.Threading;
//这个类主要是对UdpClient进行封装
//提供初始化、发送报文、接受报文、处理报文(解包)这四个接口
namespace Game.Net
{
public class USocket
{
//对Udp这个对象进行构造
UdpClient udpClient;
//定义变量
string ip = "192.168.6.23"; //用来找到服务器主机,ip地址也可能是192.168.191.1
int post = 8899; //端口用来找服务器程序
public static IPEndPoint server;
//提供初始化接口,写个构造函数就可以了
public USocket(Action<BufferEntity> dispatchNetEvent)
{
//参数为0表示系统自动分配
udpClient = new UdpClient(0);
server = new IPEndPoint(IPAddress.Parse(ip), port);
}
//需要一个队列,存储待处理的消息
ConcurrentQueue<UdpReceiveResult> awaitHandle = new ConcurrentQueue<UdpReceiveResult>();
//初始化好后开始接受网络的消息,这里使用异步的形式进行接受
//接受报文
public async void ReceiveTask()
{
//服务器可以开启线程来接受
while (UdpClient != null)
{
//用tyr-catch捕获数据异常
try
{
//等待,有数据过来才会继续往下走,返回一个数据
UdpReceiveResult result = await udpClient.ReceiveAsync();
//入队
awaitHandle.Enqueue(result);
}
catch (Exception e)
{
//打印日常的日志
Debug.LogError(e.Message);
}
}
}
//发送报文的接口
//第一个参数表示要发送的数据,第二参数是IP
public async void Send(byte[] data,IPEndPoint endPoint)
{
if (udpClient != null)
{
try
{
//用awat等待发送完毕,不会阻塞主线程
int length = await udpClient.SendAsync(data, data.Length, ip, port);
}
catch (Exception e)
{
//用$格式化字符
Debug.LogError($"发送异常:{e.Message}");
}
}
}
//发送ACK报文的接口,解包后马上调用
public async void SendACK(BufferEntity bufferEntity)
{
//因为内部已经实现了async-await的机制,所以不会阻塞到主线程的业务
await Send(bufferEntity.buffer, server);
}
//关闭udp的接口
public void Close()
{
udpClient.Close();
udpClient = null;
}
}
}