namespace BlackBlock.Network.Sockets { using System; using System.Collections.Concurrent; using System.Net; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Threading; using BlackBlock; public delegate void NetworkClientConnection(ClientWrapper client); public delegate void NetworkClientReceive(Byte[] buffer, Int32 length, ClientWrapper client); public class ServerSocket { public Socket Socket { get; private set; } public IPEndPoint LocalEndPoint { get; private set; } public String Name { get; private set; } public NetworkClientConnection OnConnect; public NetworkClientReceive OnReceive; public NetworkClientConnection OnDisconnect; public BruteForceAttackProtection AttackProtector; public Int32 ClientBufferSize; public ServerSocket(String name, UInt32 maximum, UInt32 banTime) { Name = name; AttackProtector = new BruteForceAttackProtection(maximum, banTime); } public void Prepare(int port, 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((int)SocketOptionName.MaxConnections); } 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 ClientWrapper(this, clientSocket, ClientBufferSize); InvokeOnConnect(client); client.BeginReceive(); } else clientSocket.Disconnect(false); BeginAccept(); } public void InvokeOnConnect(ClientWrapper client) { if (OnConnect != null) OnConnect(client); } public void InvokeOnReceive(Byte[] buffer, Int32 length, ClientWrapper client) { if (OnReceive != null) OnReceive(buffer, length, client); } public void InvokeOnDisconnect(ClientWrapper client) { if (!client.IsAlive) return; if (OnDisconnect != null) OnDisconnect(client); } } }