using System; using System.Collections.Generic; using System.Net.Sockets; using System.Threading; using System.Net; using System.Diagnostics; namespace TCPServerService { class RegistrationThread { int port; private Socket socket; private List allThreads = new List(); public bool checkForPings = true; public RegistrationThread(int registrationPort) { port = registrationPort; } public void handleConnection() { Utils.WriteEventLog(Program.COMPANY, "Registration Thread - Initialized on Port " + port, EventLogEntryType.Information, 34500); TcpListener myListener = new TcpListener(IPAddress.Any, port); myListener.Start(); int count = 0; while (true) { try { socket = myListener.AcceptSocket(); String clientIP = ((IPEndPoint)socket.RemoteEndPoint).Address.ToString(); Utils.WriteEventLog(Program.COMPANY, "IP " + clientIP + " connected", EventLogEntryType.Information, 34500); Service1.listOFSocket.Add(socket); Utils.WriteEventLog(Program.COMPANY, "Total connections: " + Service1.listOFSocket.Count, EventLogEntryType.Information, 34500); //Service1.writeToFile(string.Format("Total connections: {0} {1}", Service1.listOFSocket.Count.ToString(), DateTime.Now.ToString())); ReadThread RegistrationConnection = new ReadThread(socket); RegistrationConnection.OnReadException += RegistrationConnection_OnReadException; Thread LocationThreadObj = new Thread(new ThreadStart(RegistrationConnection.handleConnection)); LocationThreadObj.IsBackground = true; LocationThreadObj.Start(); allThreads.Add(RegistrationConnection); } catch (Exception e) { Utils.WriteEventLog(Program.COMPANY, "Ex in appserver:Registration thread: " + e.ToString(), EventLogEntryType.Error, 23456); //Form1.appDead = true; } Thread.Sleep(1); if (count++ > 5000) { RemoveClient(null); count = 0; } } //myListener.Stop(); } private void RegistrationConnection_OnReadException(string clientIP) { RemoveClient(clientIP); } private Object _lock = new Object(); private void RemoveClient(String clientIP) { lock (_lock) { try { // create list to store the threads that needs to be removed List toRemove = new List(); // iterate all active threads to search for lost pings foreach (ReadThread thread in allThreads) { bool pingExpired = checkForPings && (ReadThread.PING_INTERVAL_SEC * 3) < (DateTime.Now - thread.lastPingTime).TotalSeconds; //Utils.WriteEventLog(Program.COMPANY, "PING: " + thread.lastPingTime.ToShortDateString() + " | | | " // + (DateTime.Now - thread.lastPingTime).TotalSeconds, EventLogEntryType.SuccessAudit, 23456); // if 3 pings were lost if (pingExpired || (clientIP != null && thread.clientIP.Equals(clientIP))) { try { Utils.WriteEventLog(Program.COMPANY, $"Closing socket with {thread.clientIP} {(pingExpired ? "due to lost PINGS" : "closed socket")}", EventLogEntryType.Warning, 23456); // close connection, remove it and then flag it as to be removed thread.socket.Close(); Service1.listOFSocket.Remove(thread.socket); toRemove.Add(thread); } catch (Exception ex) { Utils.WriteEventLog(Program.COMPANY, "Unable to close socket: " + ex.ToString(), EventLogEntryType.Error, 23456); } } } // remove all threads that are closed due to inactive ping foreach (ReadThread thread in toRemove) { thread.isRunning = false; allThreads.Remove(thread); } } catch(Exception ex) { Utils.WriteEventLog(Program.COMPANY, "Error removing client : " + ex.ToString(), EventLogEntryType.Error, 23456); } } } public void onUdpSendingFailed(String clientIP) { RemoveClient(clientIP); } } }