using System; using System.Diagnostics; using System.Linq; using System.ServiceProcess; using System.Text; using System.Configuration; using System.Threading; using System.Collections; using System.Net.Sockets; using System.Net; using System.Timers; using System.Threading.Tasks; namespace WindowsService1 { public partial class Service1 : ServiceBase { public static volatile UdpMulticast UdpMulti = null; public static volatile Queue MessageSend = new Queue(); public static volatile Boolean appDead = false; public static NetworkStream clientStream = null; public static TcpClient client = null; private RegistrationThread RegConn = null; public static Thread RegistrationThreadObj = null; public static string ip_multicast = string.Empty; public static string port_multicast = string.Empty; public static string TcpPort = string.Empty; public static string TcpServerIP = string.Empty; public static string LocalIP = string.Empty; static string logFile = "log.log"; public Service1() { InitializeComponent(); // Turn off autologging this.AutoLog = false; } protected override void OnStart(string[] args) { //writeToFile("Service started!"); Utils.WriteEventLog("Safemobile", "SERVICE ON", EventLogEntryType.Information, 34500); if (!ConfigurationManager.AppSettings.AllKeys.Contains("ip_multicast")) { Utils.WriteEventLog("Safemobile", "AppSettings does not contain key \"ip_multicast\"", EventLogEntryType.Error, 23456); } else { ip_multicast = ConfigurationManager.AppSettings["ip_multicast"]; Utils.WriteEventLog("Safemobile", "AppSettings.ip_multicast = \"" + ip_multicast + "\"", EventLogEntryType.Information, 34500); } if (!ConfigurationManager.AppSettings.AllKeys.Contains("port_multicast")) { Utils.WriteEventLog("Safemobile", "AppSettings does not contain key \"port_multicast\"", EventLogEntryType.Error, 23456); } else { port_multicast = ConfigurationManager.AppSettings["port_multicast"]; Utils.WriteEventLog("Safemobile", "AppSettings.port_multicast = \"" + port_multicast + "\"", EventLogEntryType.Information, 34500); } if (!ConfigurationManager.AppSettings.AllKeys.Contains("TcpPort")) { Utils.WriteEventLog("Safemobile", "AppSettings does not contain key \"TcpPort\"", EventLogEntryType.Error, 23456); } else { TcpPort = ConfigurationManager.AppSettings["TcpPort"]; Utils.WriteEventLog("Safemobile", "AppSettings.TcpPort = \"" + TcpPort + "\"", EventLogEntryType.Information, 34500); } if (!ConfigurationManager.AppSettings.AllKeys.Contains("TcpServerIP")) { Utils.WriteEventLog("Safemobile", "AppSettings does not contain key \"TcpServerIP\"", EventLogEntryType.Error, 23456); } else { TcpServerIP = ConfigurationManager.AppSettings["TcpServerIP"]; Utils.WriteEventLog("Safemobile", "AppSettings.TcpServerIP = \"" + TcpServerIP + "\"", EventLogEntryType.Information, 34500); } if (!ConfigurationManager.AppSettings.AllKeys.Contains("LocalIP")) { Utils.WriteEventLog("Safemobile", "AppSettings does not contain key \"LocalIP\"", EventLogEntryType.Error, 23456); } else { LocalIP = ConfigurationManager.AppSettings["LocalIP"]; Utils.WriteEventLog("Safemobile", "AppSettings.LocalIP = \"" + LocalIP + "\"", EventLogEntryType.Information, 34500); } try { System.Timers.Timer timer1 = new System.Timers.Timer(); timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed); timer1.Interval = 20000; timer1.Enabled = true; timer1.Start(); StartPingThread(); UdpMulti = new UdpMulticast(ip_multicast, Convert.ToInt32(port_multicast)); UdpMulti.StartListen(LocalIP); UdpMulti.OnNewDataRecv += new UdpMulticast.newData4Send(udp_OnNewDataRecv); client = new TcpClient(); IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(TcpServerIP), Convert.ToInt32(TcpPort)); client.Connect(serverEndPoint); Utils.WriteEventLog("Safemobile", "Client connected at: " + TcpServerIP, EventLogEntryType.Information, 23456); //writeToFile("Client connected at: " + TcpServerIP + " " + DateTime.Now.ToString()); clientStream = client.GetStream(); System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); RegConn = new RegistrationThread(clientStream); RegConn.OnPong += RegConn_OnPong; RegistrationThreadObj = new Thread(new ThreadStart(RegConn.handleConnection)); RegistrationThreadObj.IsBackground = true; RegistrationThreadObj.Start(); } catch (Exception ex) { Utils.WriteEventLog("Safemobile", "Error conecting to Multicast" + ex.ToString(), EventLogEntryType.Error, 23456); } } private DateTime lastPongTime = DateTime.Now; private DateTime lastPingTime = DateTime.Now; private void RegConn_OnPong() { lastPongTime = DateTime.Now; } bool running = false; private readonly int PING_TIME_OUT_MS = 5000; private void StartPingThread() { running = true; Task.Factory.StartNew(() => { int count = 0; while (running) { if (count++ > PING_TIME_OUT_MS / 100) { try { String str = "PING"; int lostPongs = (int)((DateTime.Now - lastPongTime).TotalMilliseconds / PING_TIME_OUT_MS); if (lostPongs > 0) str += lostPongs; lastPingTime = DateTime.Now; clientStream.Write(asen.GetBytes(str), 0, asen.GetBytes(str).Length); Utils.WriteEventLog("Safemobile", $"{str} sent @{TcpServerIP}", EventLogEntryType.Information, 23456); } catch { } finally { count = 0; } /* if((DateTime.Now - lastPongTime).TotalMilliseconds > PING_TIME_OUT_MS * 3) { String serviceName = GetServiceName(); Process process = new Process(); process.StartInfo.FileName = "cmd"; process.StartInfo.Arguments = $"/c net stop \"{serviceName}\" & net start \"{serviceName}\""; process.Start(); Environment.Exit(1); }*/ } Thread.Sleep(100); } }); } protected String GetServiceName() { // Calling System.ServiceProcess.ServiceBase::ServiceNamea allways returns // an empty string, // see https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=387024 // So we have to do some more work to find out our service name, this only works if // the process contains a single service, if there are more than one services hosted // in the process you will have to do something else int processId = System.Diagnostics.Process.GetCurrentProcess().Id; String query = "SELECT * FROM Win32_Service where ProcessId = " + processId; System.Management.ManagementObjectSearcher searcher = new System.Management.ManagementObjectSearcher(query); foreach (System.Management.ManagementObject queryObj in searcher.Get()) { return queryObj["Name"].ToString(); } throw new Exception("Can not get the ServiceName"); } static bool IsConnected(TcpClient TCPclient) { if (TCPclient.Connected) { if ((TCPclient.Client.Poll(0, SelectMode.SelectWrite)) && (!TCPclient.Client.Poll(0, SelectMode.SelectError))) { byte[] buffer = new byte[1]; if (TCPclient.Client.Receive(buffer, SocketFlags.Peek) == 0) { return false; } else { return true; } } else { return false; } } else { return false; } } public static volatile String FromQue = ""; public static volatile ASCIIEncoding asen = new ASCIIEncoding(); static void udp_OnNewDataRecv(byte[] data, int dataLen) { try { string str = System.Text.Encoding.ASCII.GetString(data, 0, dataLen); //Utils.WriteEventLog("Safemobile", "Recive data on Multicast Send on TCP: " + str, EventLogEntryType.Information, 34500); if (FromQue.Length == 0) { if (MessageSend.Count > 0) FromQue = MessageSend.Dequeue().ToString(); } if(clientStream == null) { return; } if (FromQue.Length == 0) clientStream.Write(asen.GetBytes(str), 0, asen.GetBytes(str).Length); else { if (FromQue.CompareTo(str) == 0) { FromQue = ""; } else clientStream.Write(asen.GetBytes(str), 0, asen.GetBytes(str).Length); } if (FromQue.Length == 0) { if (MessageSend.Count > 0) FromQue = MessageSend.Dequeue().ToString(); } } catch (Exception ex) { Utils.WriteEventLog("Safemobile", "Erorr on upd rec:" + ex.ToString(), EventLogEntryType.Error, 23456); } } protected override void OnStop() { Utils.WriteEventLog("Safemobile", "SERVICE OFF", EventLogEntryType.Information, 34500); running = false; } private void timer1_Elapsed(object sender, EventArgs e) { //Utils.WriteEventLog("Safemobile", "Enter on TIMER", EventLogEntryType.Information, 34500); try { Boolean IsConnected = false; //Utils.WriteEventLog("Safemobile", "PAS1", EventLogEntryType.Information, 34500); if (client != null && client.Connected) { //Utils.WriteEventLog("Safemobile", "PAS2", EventLogEntryType.Information, 34500); if ((client.Client.Poll(0, SelectMode.SelectWrite)) && (!client.Client.Poll(0, SelectMode.SelectError))) { //Utils.WriteEventLog("Safemobile", "PAS3", EventLogEntryType.Information, 34500); byte[] buffer = new byte[1]; if (client.Client.Receive(buffer, SocketFlags.Peek) == 0) ; else IsConnected = true; } } if (IsConnected) { Utils.WriteEventLog("Safemobile", "TCP is still ON", EventLogEntryType.Information, 34500); running = true; } else { Utils.WriteEventLog("Safemobile", "TCP is OFF", EventLogEntryType.Information, 34500); // close client if not null clientStream?.Close(); client?.Close(); RegistrationThreadObj?.Join(2000); Thread.Sleep(200); Utils.WriteEventLog("Safemobile", "Distroy Thread and client", EventLogEntryType.Information, 34500); client = new TcpClient(); IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(TcpServerIP), Convert.ToInt32(TcpPort)); client.Connect(serverEndPoint); Utils.WriteEventLog("Safemobile", "Client connected at: " + serverEndPoint, EventLogEntryType.Information, 23456); //writeToFile("Client connected at: " + serverEndPoint.ToString() + " " + DateTime.Now.ToString()); clientStream = client.GetStream(); System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); RegConn = new RegistrationThread(clientStream); RegConn.OnPong += RegConn_OnPong; RegistrationThreadObj = new Thread(new ThreadStart(RegConn.handleConnection)); RegistrationThreadObj.IsBackground = true; RegistrationThreadObj.Start(); //Utils.WriteEventLog("Safemobile", "End renew the thread and client", EventLogEntryType.Information, 34500); } } catch (Exception ex) { //writeToFile("Client disconnected " + DateTime.Now.ToString()); Utils.WriteEventLog("Safemobile", "Error on timer: " + ex.ToString(), EventLogEntryType.Error, 23456); } } //internal static void writeToFile(string message) //{ // try // { // Utils.WriteEventLog("Safemobile", "enter write to file", EventLogEntryType.SuccessAudit, 23456); // if (!File.Exists(logFile)) // File.Create(logFile); // File.WriteAllText(logFile, message); // Utils.WriteEventLog("Safemobile", "exit write to file", EventLogEntryType.SuccessAudit, 23456); // } // catch // { // Utils.WriteEventLog("Safemobile", "unable to write to file", EventLogEntryType.SuccessAudit, 23456); // } //} } }