The socket system is inspired by Redux and Phoenix. I've been using this for a while and i think the problem comes from here.
PHP Code:
using System;
using System.Net;
using System.Text;
using System.Linq;
using System.Net.Sockets;
namespace PureConquer.Network.ServerSocket
{
public delegate void NetworkClientConnection(Wrapper client);
public delegate void NetworkClientReceive(byte[] buffer, int length, Wrapper client);
public class SocketServer
{
public Socket Socket { get; private set; }
public IPEndPoint LocalEndPoint { get; private set; }
public NetworkClientConnection OnConnect;
public NetworkClientReceive OnReceive;
public NetworkClientConnection OnDisconnect;
public BruteForceAttackProtection AttackProtector;
public int ClientBufferSize;
public SocketServer(uint maximum = 50, uint banTime = 60)
{
AttackProtector = new BruteForceAttackProtection(maximum, banTime);
}
public void Prepare(int port, int backlog, IPProtectionLevel protectionLevel)
{
LocalEndPoint = new IPEndPoint(IPAddress.Any, port);
Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Socket.Bind(LocalEndPoint);
Socket.SetIPProtectionLevel(protectionLevel);
Socket.NoDelay = true;
Socket.Listen(backlog);
}
public void BeginAccept()
{
Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, false);
Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true);
Socket.BeginAccept(Accept, null);
}
private void Accept(IAsyncResult result)
{
Socket clientSocket;
try
{
clientSocket = Socket.EndAccept(result);
}
catch (SocketException)
{
BeginAccept();
return;
}
if (AttackProtector.Authenticate(clientSocket))
{
clientSocket.ReceiveBufferSize = ClientBufferSize;
var client = new Wrapper(this, clientSocket, ClientBufferSize);
InvokeOnConnect(client);
client.BeginReceive();
}
else
clientSocket.Disconnect(false);
BeginAccept();
}
public void InvokeOnConnect(Wrapper client)
{
if (OnConnect != null)
OnConnect(client);
}
public void InvokeOnReceive(byte[] buffer, int length, Wrapper client)
{
if (OnReceive != null)
OnReceive(buffer, length, client);
}
public void InvokeOnDisconnect(Wrapper client)
{
if (!client.IsAlive) return;
if (OnDisconnect != null)
OnDisconnect(client);
}
}
}
PHP Code:
using System;
using System.Net;
using System.Text;
using System.Linq;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace PureConquer.Network.ServerSocket
{
public class Wrapper
{
public Socket Socket { get; private set; }
public SocketServer Server { get; private set; }
public IPEndPoint RemoteEndPoint { get; private set; }
private readonly byte[] _buffer;
public object Owner;
public Boolean IsAlive { get { return Socket.Connected; } }
public String IP
{
get
{
if (Socket != null)
return (Socket.RemoteEndPoint as IPEndPoint).Address.ToString();
else
return null;
}
}
public Wrapper(SocketServer server, Socket socket, int bufferLength)
{
Server = server;
Socket = socket;
_buffer = new byte[bufferLength];
RemoteEndPoint = (IPEndPoint)Socket.RemoteEndPoint;
Socket.NoDelay = true;
}
public void BeginReceive()
{
try
{
Socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(Receive), null);
}
catch (SocketException)
{
Server.InvokeOnDisconnect(this);
}
}
private void Receive(IAsyncResult result)
{
if (Socket != null)
{
try
{
SocketError error;
int length = Socket.EndReceive(result, out error);
if (IsAlive && error == SocketError.Success)
{
if (length > 0)
{
try
{
Server.InvokeOnReceive(_buffer, length, this);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
BeginReceive();
}
}
else
{
Server.InvokeOnDisconnect(this);
}
}
}
catch (SocketException)
{
Server.InvokeOnDisconnect(this);
}
}
}
public void Send(byte[] packet)
{
if (IsAlive)
{
try
{
Socket.Send(packet, 0, packet.Length, SocketFlags.None);
}
catch (SocketException)
{
Server.InvokeOnDisconnect(this);
}
}
}
private void EndSend(IAsyncResult result)
{
try
{
Socket.EndSend(result);
}
catch (SocketException)
{
Server.InvokeOnDisconnect(this);
}
}
public void Disconnect()
{
try
{
Socket.Disconnect(false);
}
catch (SocketException)
{
}
Server.InvokeOnDisconnect(this);
}
public override string ToString()
{
return RemoteEndPoint.ToString();
}
}
}