115 lines
4.6 KiB
C#
115 lines
4.6 KiB
C#
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> { }
|
||
} |