文章目录
1.状态:未完成
2.代码
using System;
using System.Collections.Concurrent; //线程安全的队列
using System.Collections.Generic;
using System.Net; //导入命名空间
using System.Net.Sockets;
using System.Text;
namespace MobaServer.Net
{
class USocket
{
//还需要核心对象Udp
UdpClient socket;//socket通信
//客户端跟服务器通信,要直到他的端口
//服务器IP为本地的IP,服务器现在是放在本地
string ip = "192.168.6.23";
//端口号
int port = 8899;
//把它缓存到本地上面,因为是一对多的服务器,所以再创建客户端时要将函数传递过去
Action<BufferEntity> dispatchNetEvent;
//初始化的接口
public USocket(Action<BufferEntity> dispatchNetEvent)
{
this.dispatchNetEvent = dispatchNetEvent;
//构造一下,传入端口号
socket = new UdpClient(8899);
//可以开始接受消息,开始的时候调用一下
Receive();
}
//发送消息的接口
public async void Send(byte[] data,IPEndPoint endPoint)
{
//内部使用异步发送的接口,不会阻塞主线程的运行
if(socket!=null)
{
//用try-catch捕获异常,若出现异常,服务器要断开于客户端的连接
try
{
int length = await socket.SendAsync(data, data.Length, endPoint);
//若相等,说明数据是完整发送的
if (data.Length == length)
{
}
}
catch(Exception e)
{
//关闭socket的接口
Close();
}
}
}
//发送ACK消息的接口
public async void SendACK(BufferEntity ackPackage,IPEndPoint endPoint)
{
//调用Send接口将ACK报文发送出去
//内部已经实现了await,不用加上await
Send(ackPackage.buffer, endPoint);
}
//线程安全的队列存客户端发来的消息包
ConcurrentQueue<UdpReceiveResult> awaitHandle = new System.Collections.Concurrent.ConcurrentQueue<UdpReceiveResult>();
//接受消息的接口
public async void Receive()
{
if (socket != null)
{
try
{
//可以用来等待,因为是异步的接口
//当有客户端发送消息的时候,要缓存起来,再来进行处理
UdpReceiveResult result = await socket.ReceiveAsync();
//接受消息和处理消息不要写在一起,只需要缓存就可以了
//如果写在一起,这里用的try-catch,当接受消息时,会把要处理的消息throw掉并打印
awaitHandle.Enqueue(result);//压入队列
Receive();//继续接受下一条消息
}
catch(Exception e)
{
//关闭socket的接口
Close();
}
}
}
//处理消息的接口
//关闭Socket的接口
void Close()
{
if (socket != null)
{
socket.Close();
socket = null;
}
//释放掉这个函数
if(dispatchNetEvent != null)
{
dispatchNetEvent = null;
}
//所有客户端都要清理掉,避免下次运行的时候出现相关异常
}
//创建客户端建立虚拟连接的接口
//移除客户端的接口
//查询客户端的接口
}
}