using System; using System.Text; using System.Threading; using System.Net; using System.Net.Sockets; namespace Rebex.Net { public class SimpleSocket : ISocket { private class SimpleSocketFactory : ISocketFactory { private readonly IPEndPoint _localEndPoint; public SimpleSocketFactory(IPEndPoint localEndPoint) { _localEndPoint = localEndPoint; } public ISocket CreateSocket() { return new SimpleSocket(this, _localEndPoint); } } public static ISocketFactory GetFactory(IPAddress localEndPoint) { return new SimpleSocketFactory(new IPEndPoint(localEndPoint, 0)); } private class SyncResult : IAsyncResult { private readonly object _state; private readonly ManualResetEvent _resetEvent = new ManualResetEvent(true); private object _result; public SyncResult(object state, object result) { _state = state; _result = result; } public object AsyncState { get { return _state; } } public object AsyncResult { get { return _result; } } public WaitHandle AsyncWaitHandle { get { return _resetEvent; } } public bool CompletedSynchronously { get { return true; } } public bool IsCompleted { get { return true; } } } private readonly Socket _socket; private readonly SimpleSocketFactory _factory; private SimpleSocket(SimpleSocketFactory factory, Socket socket) { _factory = factory; _socket = socket; } private SimpleSocket(SimpleSocketFactory factory, IPEndPoint localEndPoint) { _factory = factory; _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _socket.Bind(localEndPoint); } public ISocketFactory Factory { get { return _factory; } } public int Timeout { get { return 0; } set { } } public int Available { get { return _socket.Available; } } public bool Connected { get { return _socket.Connected; } } public System.Net.EndPoint LocalEndPoint { get { return _socket.LocalEndPoint; } } public System.Net.EndPoint RemoteEndPoint { get { return _socket.RemoteEndPoint; } } public SocketState GetConnectionState() { if (!Connected) return SocketState.NotConnected; if (!_socket.Poll(100, SelectMode.SelectRead)) return SocketState.Connected; if (_socket.Available > 0) return SocketState.Connected; return SocketState.NotConnected; } public bool Poll(int microSeconds, SocketSelectMode mode) { return _socket.Poll(microSeconds, (SelectMode)mode); } private static IPEndPoint GetIPEndPoint(string serverName, int serverPort) { var ep = ProxySocket.ToEndPoint(serverName, serverPort); if (ep == null) { IPHostEntry hostEntry = Dns.GetHostEntry(serverName); ep = ProxySocket.ToEndPoint(hostEntry, serverPort); } return ep; } public void Connect(System.Net.EndPoint remoteEP) { _socket.Connect(remoteEP); } public void Connect(string serverName, int serverPort) { IPEndPoint endPoint = GetIPEndPoint(serverName, serverPort); _socket.Connect(endPoint); } public IAsyncResult BeginConnect(System.Net.EndPoint remoteEP, AsyncCallback callback, object state) { return _socket.BeginConnect(remoteEP, callback, state); } public IAsyncResult BeginConnect(string serverName, int serverPort, AsyncCallback callback, object state) { IPEndPoint endPoint = GetIPEndPoint(serverName, serverPort); return _socket.BeginConnect(endPoint, callback, state); } public void EndConnect(IAsyncResult asyncResult) { _socket.EndConnect(asyncResult); } public EndPoint Listen(ISocket controlSocket) { _socket.Listen(0); return _socket.LocalEndPoint; } public IAsyncResult BeginListen(ISocket controlSocket, AsyncCallback callback, object state) { IPEndPoint ep = (IPEndPoint)controlSocket.LocalEndPoint; _socket.Bind(new IPEndPoint(ep.Address, 0)); _socket.Listen(0); SyncResult result = new SyncResult(state, _socket.LocalEndPoint); if (callback != null) callback(result); return result; } public EndPoint EndListen(IAsyncResult asyncResult) { SyncResult result = asyncResult as SyncResult; if (result == null) throw new ArgumentException("The IAsyncResult object supplied to EndListen was not returned from the corresponding BeginListen method on this class.", "asyncResult"); return (EndPoint)result.AsyncResult; } public ISocket Accept() { Socket socket = _socket.Accept(); return new SimpleSocket(_factory, socket); } public IAsyncResult BeginAccept(AsyncCallback callback, object state) { return _socket.BeginAccept(callback, state); } public ISocket EndAccept(IAsyncResult asyncResult) { Socket socket = _socket.EndAccept(asyncResult); return new SimpleSocket(_factory, socket); } public int Send(byte[] buffer, int offset, int count, SocketFlags socketFlags) { return _socket.Send(buffer, offset, count, socketFlags); } public IAsyncResult BeginSend(byte[] buffer, int offset, int count, SocketFlags socketFlags, AsyncCallback callback, object state) { return _socket.BeginSend(buffer, offset, count, socketFlags, callback, state); } public int EndSend(IAsyncResult asyncResult) { return _socket.EndSend(asyncResult); } public int Receive(byte[] buffer, int offset, int count, SocketFlags socketFlags) { return _socket.Receive(buffer, offset, count, socketFlags); } public IAsyncResult BeginReceive(byte[] buffer, int offset, int count, SocketFlags socketFlags, AsyncCallback callback, object state) { return _socket.BeginReceive(buffer, offset, count, socketFlags, callback, state); } public int EndReceive(IAsyncResult asyncResult) { return _socket.EndReceive(asyncResult); } public void Shutdown(SocketShutdown how) { _socket.Shutdown(how); } public void Close() { _socket.Close(); } } }