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();
}
}
}
}
}