/// <summary> /// Escucha nuevos clientes TCP que quieran establecer comunicación con ésta máquina /// Si ocurre un error se notifica en errorNetworkingHandler /// </summary> private void listenTCPClients() { try { while (true) { TcpClient tcpClient = tcpListener.AcceptTcpClient(); commHandler.informationNetworkingHandler("TCP: new client detected"); tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontRoute, true); tcpClient.LingerState.LingerTime = 0; tcpClient.LingerState.Enabled = false; IPAddress ip = ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address; Thread clientThread = new Thread(new ParameterizedThreadStart(listenTCPMessages)); RemoteMachine remoteMachine = new RemoteMachine(ip, tcpClient, clientThread); clientThread.Start(remoteMachine); RemoteMachine oldRemoteMachine = tcpServerList.getRemoteMachine(ip); if (oldRemoteMachine != null) { oldRemoteMachine.close(); tcpServerList.remove(oldRemoteMachine); } tcpServerList.add(ip, remoteMachine); commHandler.informationNetworkingHandler("TCP: new client connected"); } } catch (ThreadAbortException e) { throw e; } catch (Exception e) { commHandler.informationNetworkingHandler("TCP WARNING: TCP listener has stopped!! " + e.Message); } }
/// <summary> /// Desconecta los servicios TCP asociados a una maquina remota /// </summary> /// <param name="o">La ip de la maquina remota a desconectar en formato de String o la maquina remota</param> private void disconnectFromAsync(Object o) { try { commHandler.informationNetworkingHandler("TCP: disconnection..."); if (o.GetType().Equals(typeof(IPAddress))) { IPAddress machineIp = (IPAddress)o; RemoteMachine machine = tcpServerList.getRemoteMachine(machineIp); commHandler.informationNetworkingHandler("TCP: close signal"); machine.close(); commHandler.informationNetworkingHandler("TCP: remove from queue"); tcpServerList.remove(machine); } else if (o.GetType().Equals(typeof(RemoteMachine))) { RemoteMachine machine = (RemoteMachine)o; commHandler.informationNetworkingHandler("TCP: close signal"); machine.close(); commHandler.informationNetworkingHandler("TCP: remove from queue"); tcpServerList.remove(machine); } commHandler.informationNetworkingHandler("TCP: disconnection... ok!"); } catch (ThreadAbortException e) { throw e; } catch (Exception e) { commHandler.informationNetworkingHandler("TCP: disconnection... failed! " + e.Message); } }
/// <summary> /// Agrega una maquina a la colección, asocia una IP a la maquina como llave de la colección /// </summary> /// <param name="ip">la ip de la máquina</param> /// <param name="newRemoteMachine">la maquina a agregar</param> public void add(IPAddress ip, RemoteMachine newRemoteMachine) { lock (thisLock) { remoteMachineCollection.Add(ip, newRemoteMachine); } }
/// <summary> /// Remueve a una maquina de la colección /// </summary> /// <param name="remoteMachine">la maquina a remover</param> /// <returns>true si la maquina existía, false si no</returns> public bool remove(RemoteMachine remoteMachine) { lock (thisLock) { RemoteMachine listedRemoteMachine = getRemoteMachine(remoteMachine.Ip); if (listedRemoteMachine != null && remoteMachine.Id.Equals(listedRemoteMachine.Id)) { remoteMachineCollection.Remove(listedRemoteMachine.Ip); return true; } return false; } }
/// <summary> /// Remueve a una maquina de la colección /// </summary> /// <param name="remoteMachine">la maquina a remover</param> /// <returns>true si la maquina existía, false si no</returns> public bool remove(RemoteMachine remoteMachine) { lock (thisLock) { RemoteMachine listedRemoteMachine = getRemoteMachine(remoteMachine.Ip); if (listedRemoteMachine != null && remoteMachine.Id.Equals(listedRemoteMachine.Id)) { remoteMachineCollection.Remove(listedRemoteMachine.Ip); return(true); } return(false); } }
/// <summary> /// Construye un array con los elementos de la lista /// </summary> /// <returns>Un array con los elementos de la lista</returns> public RemoteMachine[] toObjectArray() { lock (thisLock) { RemoteMachine[] us = new RemoteMachine[remoteMachineCollection.Count]; IDictionaryEnumerator en = remoteMachineCollection.GetEnumerator(); int i = 0; while (en.MoveNext()) { us[i] = (RemoteMachine)en.Value; i++; } return(us); } }
/// <summary> /// Se conecta a una máquina remota por TCP para enviarle mensajes posteriormente /// Si ocurre un error se notifica en informationNetworkingHandler /// </summary> /// <param name="o">La dirección IP de la máquina remota en formato IPAddress</param> private void connectToAsync(Object o) { try { commHandler.informationNetworkingHandler("TCP: connection..."); IPAddress serverIp = (IPAddress)o; TcpClient tcpClient = new TcpClient(new IPEndPoint(tcpAddress, 0)); tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontRoute, true); tcpClient.LingerState.LingerTime = 0; tcpClient.LingerState.Enabled = false; //Conexion asincrona con time out IAsyncResult result = tcpClient.BeginConnect(serverIp, netData.TcpPort, null, null); bool success = result.AsyncWaitHandle.WaitOne(netData.TcpConnectTimeOut, true); if (!success) { commHandler.informationNetworkingHandler("TCP: connection... time out!"); return; } else { tcpClient.EndConnect(result); Thread clientThread = new Thread(new ParameterizedThreadStart(listenTCPMessages)); RemoteMachine remoteMachine = new RemoteMachine(serverIp, tcpClient, clientThread); clientThread.Start(remoteMachine); RemoteMachine oldRemoteMachine = tcpServerList.getRemoteMachine(serverIp); if (oldRemoteMachine != null) { oldRemoteMachine.close(); tcpServerList.remove(oldRemoteMachine); } tcpServerList.add(serverIp, remoteMachine); commHandler.informationNetworkingHandler("TCP: connection... ok!"); } } catch (ThreadAbortException e) { throw e; } catch (Exception e) { commHandler.informationNetworkingHandler("TCP: connection... failed! " + e.Message); commHandler.informationNetworkingHandler(e.StackTrace); } }
/// <summary> /// Envía un mensaje TCP a la maquina cuya ip es pasada como parámetro /// Si ocurre un error se arroja /// </summary> /// <param name="netMessage">El mensaje a envíar</param> /// <param name="ip">la IP de la máquina destino</param> public bool sendTcpMessage(NetMessage netMessage, IPAddress ip) { try { RemoteMachine remoteMachine = tcpServerList.getRemoteMachine(ip); if (remoteMachine != null) { try { remoteMachine.sendNetMessage(netMessage, netData.TimeOutWriteTCP); } catch (ThreadAbortException e) { throw e; } catch (Exception e) { commHandler.informationNetworkingHandler("TCP WARINING: send failed " + e.Message); if (remoteMachine.Fails >= netData.SendFailsToDisconnect) { disconnectFrom(remoteMachine); } return(false); } return(true); } else { throw new Exception("there is no TCP link with that remote machine"); } } catch (ThreadAbortException e) { throw e; } catch (Exception e) { commHandler.informationNetworkingHandler("TCP WARNING: send failed " + e.Message); return(false); } }
/// <summary> /// Escucha mensajes TCP recibidos. /// Este método es gatillado por los threads asignados a cada cliente ya conectado. /// Si ocurre un error se notifica en errorNetworkingHandler /// </summary> /// <param name="o">la máquina remota que envía el mensaje, debe ser un objeto RemoteMachine</param> private void listenTCPMessages(Object o) { RemoteMachine remoteMachine = (RemoteMachine)o; try { while (true) { StringBuilder blockData = new StringBuilder(); NetworkStream nStream = remoteMachine.TcpClient.GetStream(); byte[] length = new byte[4]; int m = nStream.Read(length, 0, 4); while (m < 4) { m += nStream.Read(length, m, 4 - m); } byte[] data = new byte[BitConverter.ToInt32(length, 0)]; int n = nStream.Read(data, 0, data.Length); while (n < data.Length) { n += nStream.Read(data, n, data.Length - n); } NetMessage message = new NetMessage(data); addTCPMessages(message); } } catch (ThreadAbortException e) { throw e; } catch (Exception e) { commHandler.informationNetworkingHandler("TCP WARNING: header reading failed " + e.Message); disconnectFrom(remoteMachine); } }
/// <summary> /// Desconecta los servicios TCP asociados a una maquina remota /// </summary> /// <param name="machine">la maquina a desconectar debe ser un String</param> public void disconnectFrom(RemoteMachine machine) { disconnectFromAsync(machine); }
/// <summary> /// Construye un array con los elementos de la lista /// </summary> /// <returns>Un array con los elementos de la lista</returns> public RemoteMachine[] toObjectArray() { lock (thisLock) { RemoteMachine[] us = new RemoteMachine[remoteMachineCollection.Count]; IDictionaryEnumerator en = remoteMachineCollection.GetEnumerator(); int i = 0; while (en.MoveNext()) { us[i] = (RemoteMachine)en.Value; i++; } return us; } }
/// <summary> /// Escucha nuevos clientes TCP que quieran establecer comunicación con ésta máquina /// Si ocurre un error se notifica en errorNetworkingHandler /// </summary> private void listenTCPClients() { try { while (true) { TcpClient tcpClient = tcpListener.AcceptTcpClient(); commHandler.informationNetworkingHandler("TCP: new client detected"); tcpClient.LingerState.LingerTime = 0; tcpClient.LingerState.Enabled = false; IPAddress ip = ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address; RemoteMachine remoteMachine = new RemoteMachine(ip, tcpClient); remoteMachine.Buffer = new byte[4]; remoteMachine.TcpClient.GetStream().BeginRead(remoteMachine.Buffer, 0, remoteMachine.Buffer.Length, listenTCPMessages, remoteMachine); RemoteMachine oldRemoteMachine = tcpServerList.getRemoteMachine(ip); if (oldRemoteMachine != null) { oldRemoteMachine.close(); tcpServerList.remove(oldRemoteMachine); //oldServerList.add(oldRemoteMachine.Ip, oldRemoteMachine); } tcpServerList.add(ip, remoteMachine); commHandler.informationNetworkingHandler("TCP: new client connected"); } } catch (ThreadAbortException e) { throw e; } catch (Exception e) { commHandler.informationNetworkingHandler("TCP WARNING: TCP listener has stopped!! " + e.Message); } }
/// <summary> /// Se conecta a una máquina remota por TCP para enviarle mensajes posteriormente /// Si ocurre un error se notifica en informationNetworkingHandler /// </summary> /// <param name="o">La dirección IP de la máquina remota, debe ser un String</param> private void connectToAsync(Object o) { try { commHandler.informationNetworkingHandler("TCP: connection..."); IPAddress serverIp = (IPAddress)o; TcpClient tcpClient = new TcpClient(new IPEndPoint(tcpAddress, 0)); tcpClient.LingerState.LingerTime = 0; tcpClient.LingerState.Enabled = false; IAsyncResult result = tcpClient.Client.BeginConnect(new IPEndPoint(serverIp, netData.TcpPort), null, null); bool success = result.AsyncWaitHandle.WaitOne(netData.TcpConnectTimeOut, false); if (!success) { commHandler.informationNetworkingHandler("TCP: connection... time out!"); return; } else { tcpClient.Client.EndConnect(result); RemoteMachine remoteMachine = new RemoteMachine(serverIp, tcpClient); remoteMachine.Buffer = new byte[4]; remoteMachine.TcpClient.GetStream().BeginRead(remoteMachine.Buffer, 0, remoteMachine.Buffer.Length, listenTCPMessages, remoteMachine); RemoteMachine oldRemoteMachine = tcpServerList.getRemoteMachine(serverIp); if (oldRemoteMachine != null) { oldRemoteMachine.close(); tcpServerList.remove(oldRemoteMachine); } tcpServerList.add(serverIp, remoteMachine); commHandler.informationNetworkingHandler("TCP: connection... ok!"); } } catch (ThreadAbortException e) { throw e; } catch (Exception e) { commHandler.informationNetworkingHandler("TCP: connection... failed! " + e.Message); commHandler.informationNetworkingHandler(e.StackTrace); } }
/// <summary> /// Desconecta los servicios TCP asociados a una maquina remota /// </summary> /// <param name="machine">la maquina a desconectar debe ser un String</param> public void disconnectFrom(RemoteMachine machine) { //disconnectFromAsync(machine); killRemoteMachine(machine); }