using System.Net.Sockets; namespace PSO2SERVER.Network { public class SocketClient { public delegate void ConnectionLostDelegate(); public delegate void DataReceivedDelegate(byte[] data, int size); private readonly byte[] _readBuffer, _writeBuffer; private readonly SocketServer _server; private int _writePosition = 0; public SocketClient(SocketServer server, TcpClient socket) { _server = server; Socket = socket; _readBuffer = new byte[1024 * 16]; _writeBuffer = new byte[1024 * 1024]; // too high? too low? not sure } public TcpClient Socket { get; private set; } public event DataReceivedDelegate DataReceived; public event ConnectionLostDelegate ConnectionLost; public bool NeedsToWrite { get { return (_writePosition > 0); } } public bool OnReadable() { try { var read = Socket.Client.Receive(_readBuffer); if (read == 0) { // Connection failed, presumably ConnectionLost(); _server.NotifyConnectionClosed(this); return false; } DataReceived(_readBuffer, read); return true; } catch (SocketException) { ConnectionLost(); _server.NotifyConnectionClosed(this); return false; } } public bool OnWritable() { try { var write = Socket.Client.Send(_writeBuffer, 0, _writePosition, SocketFlags.None); if (write == 0) { // Connection failed, presumably ConnectionLost(); _server.NotifyConnectionClosed(this); return false; } System.Array.Copy(_writeBuffer, write, _writeBuffer, 0, _writePosition - write); _writePosition -= write; return true; } catch (SocketException) { ConnectionLost(); _server.NotifyConnectionClosed(this); return false; } } public void Write(byte[] blob) { if ((_writePosition + blob.Length) > _writeBuffer.Length) { // Buffer exceeded! throw new System.Exception("too much data in write queue"); } System.Array.Copy(blob, 0, _writeBuffer, _writePosition, blob.Length); _writePosition += blob.Length; } public void Close() { ConnectionLost(); _server.NotifyConnectionClosed(this); Socket.Close(); } } }