HISP/HorseIsleServer/LibHISP/Server/Network/Transport.cs

128 lines
3.5 KiB
C#

using HISP.Util;
using System;
using System.Collections.Generic;
using System.Net.Sockets;
namespace HISP.Server.Network
{
public abstract class Transport : ITransport
{
internal Socket socket;
internal string remoteIp;
internal Action<byte[]> onReceiveCallback;
internal Action onDisconnectCallback;
internal List<byte> currentPacket = new List<byte>();
internal byte[] workBuffer = new byte[0xFFFF];
internal bool isDisconnecting = false;
public abstract void ProcessReceivedPackets(int available, byte[] buffer);
public abstract string Name { get; }
internal virtual bool checkForError(SocketAsyncEventArgs e)
{
if (isDisconnecting || socket == null || e.BytesTransferred <= 0 || !socket.Connected || e.SocketError != SocketError.Success)
{
Disconnect();
return true;
}
else
{
return false;
}
}
internal virtual void receivePackets(object sender, SocketAsyncEventArgs e)
{
do
{
if (!checkForError(e))
ProcessReceivedPackets(e.BytesTransferred, e.Buffer);
else
break;
} while (!socket.ReceiveAsync(e));
}
public virtual string Ip
{
get
{
return this.remoteIp;
}
}
public virtual bool Disconnected
{
get
{
return this.isDisconnecting;
}
}
internal virtual void passObjects(Socket socket, Action<byte[]> onReceive, Action onDisconnect)
{
socket.SendTimeout = 10 * 1000; // 10sec
socket.ReceiveTimeout = 10 * 1000; // 10sec
this.socket = socket;
this.onReceiveCallback = onReceive;
this.onDisconnectCallback = onDisconnect;
this.remoteIp = Helper.GetIp(socket.RemoteEndPoint);
}
public virtual void Accept(Socket socket, Action<byte[]> onReceive, Action onDisconnect)
{
passObjects(socket, onReceive, onDisconnect);
SocketAsyncEventArgs e = new SocketAsyncEventArgs();
e.Completed += receivePackets;
e.SetBuffer(workBuffer, 0, workBuffer.Length);
if (!socket.ReceiveAsync(e))
receivePackets(null, e);
}
public virtual void Disconnect()
{
if (this.isDisconnecting)
return;
this.isDisconnecting = true;
// Close Socket
if (socket != null)
{
try
{
socket.Disconnect(false);
socket.Dispose();
socket = null;
}
catch (SocketException e) { }
catch (ObjectDisposedException e) { };
}
onDisconnectCallback();
}
public virtual void Send(byte[] data)
{
if (Disconnected) return;
if (data == null) return;
try
{
socket.Send(data);
}
catch (ObjectDisposedException)
{
if (!Disconnected)
Disconnect();
}
}
}
}