using System; using System.Net; using System.Net.Sockets; using System.Collections.Generic; using System.Collections; using System.Text; using System.IO; namespace Holo.Socketservers { /// /// Asynchronous socket server for the Remote connections. /// public static class remoteSocketServer { private static Socket socketHandler; private static int _Port; private static HashSet _activeRemoteConnections; private static bool SocketClosed = false; internal static bool Init(int bindPort) { _Port = bindPort; _activeRemoteConnections = new HashSet(); socketHandler = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { socketHandler.Bind(new IPEndPoint(IPAddress.Any, bindPort)); socketHandler.Listen(25); socketHandler.BeginAccept(new AsyncCallback(connectionRequest), socketHandler); Out.WriteLine("Conexiones Remotas escuchadas desde el puerto " + bindPort); return true; } catch { Out.WriteError("El puerto " + bindPort + " es inválido o esta en uso."); return false; } } internal static void freeRemoteConnection(int connectionID) { if (_activeRemoteConnections.Contains(connectionID)) { _activeRemoteConnections.Remove(connectionID); } } private static void connectionRequest(IAsyncResult iAr) { try { int connectionID = 0; for (int i = 1; i <= 2; i++) { if (_activeRemoteConnections.Contains(i) == false) { connectionID = i; break; } } if (connectionID > 0) { Socket newSocket = ((Socket)iAr.AsyncState).EndAccept(iAr); string IP = newSocket.RemoteEndPoint.ToString().Split(':')[0]; if (connectionID > 2) { newSocket.Shutdown(SocketShutdown.Both); newSocket.Close(); Socketservers.remoteSocketServer.freeRemoteConnection(connectionID); } else { Out.WriteAlert("Se establecio una nueva conexión remota"); remoteConnection newConnection = new remoteConnection(newSocket, IP); socketHandler.BeginAccept(new AsyncCallback(connectionRequest), socketHandler); } } } catch { } socketHandler.BeginAccept(new AsyncCallback(connectionRequest), socketHandler); } private class remoteConnection { private Socket Connector; private byte[] dataBuffer = new byte[10001]; private string IP; internal remoteConnection(Socket Connector, string IP) { this.Connector = Connector; this.IP = IP; Connector.BeginReceive(dataBuffer, 0, dataBuffer.Length, SocketFlags.None, new AsyncCallback(dataArrival), null); } private void dataArrival(IAsyncResult iAr) { try { int bytesReceived = new int(); try { bytesReceived = Connector.EndReceive(iAr); } catch { return; } string Data = System.Text.Encoding.Default.GetString(dataBuffer, 0, bytesReceived); string remoteHeader = Data.ToString().Substring(0, 4); string[] remoteData = Data.ToString().Substring(4).Split(Convert.ToChar(2)); #region Remote trigger commands switch (remoteHeader) { case "RMNC": { int Port = int.Parse(remoteData[1]); replyConnection.Init(Port, IP); replyConnection.sendData("RMCS"); Eucalypt.remoteConnection = true; break; } } #endregion } catch { } } } public static class replyConnection { private static TcpClient ConsoleConnection; public static void Init(int Port, string IP) { try { ConsoleConnection = new TcpClient(IP, Port); } catch { Out.WriteError("No ha sido posible la conexión al InfoConsole."); Eucalypt.remoteConnection = false; return; } } public static void sendData(string Data) { NetworkStream RemoteEmu = ConsoleConnection.GetStream(); StreamWriter sendData = new StreamWriter(RemoteEmu); try { sendData.WriteLine(Data); sendData.Flush(); } catch { Eucalypt.remoteConnection = false; Out.WriteError("No ha sido posible enviar datos. Quizá el InfoConsole ya no esta encendido."); RemoteEmu.Close(); } } } } }