BITFALL/Assets/Plugins/GameDesigner/Network/Gcp/Server/TcpServerIOCP.cs

115 lines
4.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

namespace Net.Server
{
using Net.Share;
using global::System;
using global::System.Collections.Generic;
using global::System.Net;
using global::System.Net.Sockets;
using global::System.Threading;
using Debug = Event.NDebug;
using Net.System;
/// <summary>
/// tcp 输入输出完成端口服务器
/// <para>Player:当有客户端连接服务器就会创建一个Player对象出来, Player对象和XXXClient是对等端, 每当有数据处理都会通知Player对象. </para>
/// <para>Scene:你可以定义自己的场景类型, 比如帧同步场景处理, mmorpg场景什么处理, 可以重写Scene的Update等等方法实现每个场景的更新和处理. </para>
/// </summary>
public class TcpServerIocp<Player, Scene> : TcpServer<Player, Scene> where Player : NetPlayer, new() where Scene : NetScene<Player>, new()
{
protected override void StartSocketHandler()
{
AcceptHandler();
}
protected override void CreateServerSocket(ushort port)
{
Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var ip = new IPEndPoint(IPAddress.Any, port);
Server.NoDelay = true;
Server.Bind(ip);
Server.Listen(LineUp);
}
private void AcceptHandler()
{
try
{
if (!IsRunServer)
return;
if (ServerArgs == null)
{
ServerArgs = new SocketAsyncEventArgs();
ServerArgs.Completed += OnIOCompleted;
}
ServerArgs.AcceptSocket = null;// 重用前进行对象清理
if (!Server.AcceptAsync(ServerArgs))
OnIOCompleted(null, ServerArgs);
}
catch (Exception ex)
{
Debug.Log($"接受异常:{ex}");
}
}
protected override void OnIOCompleted(object sender, SocketAsyncEventArgs args)
{
Socket clientSocket = null;
switch (args.LastOperation)
{
case SocketAsyncOperation.Accept:
try
{
clientSocket = args.AcceptSocket;
if (clientSocket.RemoteEndPoint == null)
return;
var client = AcceptHander(clientSocket, clientSocket.RemoteEndPoint);
client.ReceiveArgs = new SocketAsyncEventArgs();
client.ReceiveArgs.UserToken = client;
client.ReceiveArgs.RemoteEndPoint = clientSocket.RemoteEndPoint;
client.ReceiveArgs.SetBuffer(new byte[ushort.MaxValue], 0, ushort.MaxValue);
client.ReceiveArgs.Completed += OnIOCompleted;
if (!clientSocket.ReceiveAsync(client.ReceiveArgs))
OnIOCompleted(null, client.ReceiveArgs);
}
catch (Exception ex)
{
Debug.LogError(ex.ToString());
}
finally
{
AcceptHandler();
}
break;
case SocketAsyncOperation.Receive:
var client1 = args.UserToken as Player;
int count = args.BytesTransferred;
if (count > 0 & args.SocketError == SocketError.Success)
{
var buffer = BufferPool.Take();
buffer.Count = count;
Buffer.BlockCopy(args.Buffer, args.Offset, buffer, 0, count);
receiveCount += count;
receiveAmount++;
if (client1.isDispose)
{
BufferPool.Push(buffer);
return;
}
ResolveBuffer(client1, ref buffer);
BufferPool.Push(buffer);
clientSocket = client1.Client;
if (!clientSocket.Connected)
return;
if (!clientSocket.ReceiveAsync(args))
OnIOCompleted(null, args);
}
break;
}
}
}
/// <summary>
/// 默认tcpiocp服务器当不需要处理Player对象和Scene对象时可使用
/// </summary>
public class TcpServerIocp : TcpServerIocp<NetPlayer, DefaultScene> { }
}