tcplistener and winxp service

i have a windows service that creates a tcplistener socket and waits for incoming connections. this service should allow connections before and after a user logs in and out, but it seems to not be working correctly. i keep getting this message, any ideas

No connection could be made because the target machine actively refused it



Answer this question

tcplistener and winxp service

  • Duncan Faulkner

    Looks good to me. For an impartial and thorough review, consider using FxCop. Recommended.


  • Xaviervp

    it seems that my service runs on wired nic cards but not wireless nic cards. what service could i depend on to make sure that my service runs correctly on both. or better yet how can i make sure that my service is that last service to start Here are the changes i made to the installer class.

    [RunInstaller(true)]

    public class ClientInstaller : Installer

    {

    /// <summary>

    /// Public Constructor for WindowsServiceInstaller - Put all of your Initialization code here.

    /// </summary>

    public ClientInstaller()

    {

    ServiceProcessInstaller serviceProcessInstaller = new ServiceProcessInstaller();

    ServiceInstaller serviceInstaller = new ServiceInstaller();

    serviceProcessInstaller.Account = ServiceAccount.LocalSystem;

    serviceInstaller.DisplayName = "clientListener";

    serviceInstaller.Description = "waits for the following commands shutdown or reboot and then performs that action on the computer";

    serviceInstaller.StartType = ServiceStartMode.Automatic;

    serviceInstaller.ServicesDependedOn = new string[] { "Remote Procedure Call (RPC)", "Computer Browser" };

    //This must be identical to the WindowsService.ServiceBase name set in the Client class constructor

    serviceInstaller.ServiceName = "clientListener";

    this.Installers.Add(serviceProcessInstaller);

    this.Installers.Add(serviceInstaller);

    }

    }


  • NBtech

    after looking at the code does it look overall like good coding practices were used having a senior software engineer look at your code and picking it apart helps me improve my coding style. thanks for taking the time to look it over!!!
  • Curt Broyles

    i think that my problem is with the MySql connection. As you can see i have messages that are being posted to the EventLog. I see that in the UpdateDatabase method (renamed from InitialConnection) that method starts then gives an error then stops. It should start and stop with no errors. the exception that i am receiving is, and a simple restart of the service fixes the problem. I am reposting the code to UpdateDatabase so that you can see the differences between InitialConnection and UpdateDatabase methods. both should be basically the same except for name changes and some changes i made to the code, since the last postings. I have a username and pass which is the same as the computers name (hostname)

    0 - Unable to connect to any of the specified MySQL host

    private void UpdateDatabase()

    {

    EventLog.WriteEntry("clientListener.UpdateDatabase", "UpdateDatabase starting");

    //initial connection to database

    MySqlCommand MyCommand = null;

    MySqlDataReader dr = null;

    String sHostname = Dns.GetHostName();

    MySqlConnection MyConnection = new MySqlConnection("server=admin1;username=" + sHostname + ";password=" + sHostname + ";database=timeout");

    EventLog.WriteEntry("clientListener.UpdateDatabase", "MyConnection.ConnectionString " + MyConnection.ConnectionString);

    try

    {

    //check for values in HostName, ipaddress, and iFlag if they do not exist add them else continue

    String sHostName = Dns.GetHostName();

    MyCommand = new MySqlCommand("SELECT * FROM complist WHERE HostName='" + sHostName + "'", MyConnection);

    MyConnection.Open();

    dr = MyCommand.ExecuteReader();

    if (!dr.Read())

    {

    String sIPAdd = Dns.GetHostEntry(sHostName).AddressList[0].ToString();

    MyCommand = new MySqlCommand("INSERT INTO complist VALUES('" + sHostName + "','" + sIPAdd + "',0)", MyConnection);

    dr.Close();

    dr = MyCommand.ExecuteReader();

    }

    dr.Close();

    }

    catch (ThreadAbortException)

    {

    EventLog.WriteEntry("clientListener.UpdateDatabase", "Aborted");

    }

    catch (MySqlException ex)

    {

    EventLog.WriteEntry("clientListener.UpdateDatabase", ex.Number + " - " + ex.Message);

    }

    MyConnection.Close();

    EventLog.WriteEntry("clientListener.UpdateDatabase", "UpdateDatabase exiting");

    }


  • MaryAnn80

    Hi,

    Absolutely its good coding practices but as a SSE, you need to follow good programming practice too. Its seems to be fine as of now in your code but just telling you because this must be taken care IMHO and its more important than coding practice.

    Regards,



  • Tryin2Bgood

    i made a mistake it is the ListenToServer thread that is causing the problem. This is a windows service that should allow connections to be made before a user logs in. The problem is fixed when i log in AND restart the service. i keep getting the same error, connection actively refused, something like that. its my initial error that i listed at the top! what a pain! does this have something to do with how the service is running and its user status
  • SentinelBL

    Aaron Sulwer wrote:

    private void ListenToServer()

    {

    EventLog.WriteEntry("clientListener.ListenToServer", "ListenToServer starting");

    IPAddress localhostAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];

    Int32 iPort = 63000;

    TcpListener tcpList = new TcpListener(localhostAddress, iPort);

    try

    {

    tcpList.Start();

    while (tcpList.Pending() == false)

    Thread.Sleep(1000); //every 1 second

    TcpClient tcpClient = tcpList.AcceptTcpClient();

    NetworkStream ns = tcpClient.GetStream();

    StreamReader sr = new StreamReader(ns);

    String sMessage = sr.ReadLine();

    StreamWriter sw = new StreamWriter(ns);

    sw.WriteLine("###OK### From Server");

    sw.Flush();

    sr.Close();

    sw.Close();

    ns.Close();

    tcpClient.Close();

    tcpList.Stop();

    switch (sMessage)
    :
    :

    Hi,
    1. it seems that you are accepting the command once only. So the TcpListener will be started on reboot only but what if the client gets LogOff command then the service will be started but the TcpListener will be closed so in that case it will not accept the new connection anymore.

    The line shown above as bold and in red color is the problem. It shows that on first connection to the listener, it accepts the conenction, processes on it and then CLOSES the SERVER. So, it can never accept connections anymore after execution of that line. This is the same which i have doubted in my previous post.
    Remove this line, it should solve your problem.

    Also to accept further connection, you should call tcpList.AcceptTcpClient() again at the same place where you are closing tcpList. So just replace it and it should work fine.

    2. You should close the tcpList in OnStop method so when service gets shutdown, it closes the listener and when service starts, it starts the listener.

    If your problem is something else than what i described above then please inform me that how exactly the flow is working.

    What i understood from code is, on service starts its starting the listener and wait for the connection from tcpclient. When someone connects to this server, it will read the command, send server "ok" status to the client and then closes the connection and do process based on the command received. You might have noticed that your code will work properly if the command is reboot, shutdown but you will be getting the exception if your first command is "LogOff" and then your another TcpClient tries to connect with this listener.

    So correct me if i am making any mistake,

    HTH,



  • Chas4

    i am still having my initial problem, it looks like i do not have network access with the service. how can i correct this
  • armie

    The Sleep(1000) call is a problem too. Just remove the entire while loop and call AcceptTcpClient() right away. The thread will block and immediately spring back into action when a connection request is received.


  • TL Stephan

    first off, i narrowed my errors down to the MySql error. i believe this is causing the TcpListener error and is a direct cause of it. I moved things around in my code so that the UpdateDatabase thread starts and exits first before the ListenToServer thread starts. I made sure that the ListenToServer thread starts last! I think because the database cannot be reached, something to due with no user being logged in, the ListenToServer thread isnt working correctly!
  • joeydj

    The windows service will be keep working in this case.
    The main thing is make sure that TcpListener keeps listening for incoming connections. You must accept connection after receiving some connection from client and after it disconnects. Many times we forget to call again accept method after some operation.

    The exception message you wrote says that your TcpListener is not accepting connection.

    If you are sure that it does the same then please post your code so I can look into it.

    HTH,



  • jatdex

    i marked this as having an answer but it was not fully answered as i am still having the same problem
  • Andy Ho

    using System; //String & IntPtr

    using System.ServiceProcess; //Client base class ServiceBase

    using System.ComponentModel; //RunInstaller

    using System.Configuration.Install; //ClientInstaller base class Installer

    using System.Diagnostics; //EventLog

    using System.Threading; //Thread

    using MySql.Data.MySqlClient; //MySql

    using System.Data; //MySql

    using System.Runtime.InteropServices; //DllImport

    using System.IO; //StreamReader

    using System.Net; //Dns & IPAddress

    using System.Net.Sockets; //TcpListener, TcpClient & NetworkStream

    namespace Client

    {

    public class Client : ServiceBase

    {

    [DllImport("advapi32.dll", SetLastError = true)]

    private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]

    private extern static bool CloseHandle(IntPtr handle);

    private Thread thread1 = null;

    private Thread thread2 = null;

    public Client()

    {

    CanShutdown = true;

    ServiceName = "clientListener";

    }

    protected override void OnStart(string[] args)

    {

    EventLog.WriteEntry("clientListener.OnStart", "clientListerner.OnStart");

    thread1 = new Thread(new ThreadStart(ListenToServer));

    thread1.Start();

    thread2 = new Thread(new ThreadStart(UpdateDatabase));

    thread2.Start();

    base.OnStart(args);

    }

    protected override void OnStop()

    {

    EventLog.WriteEntry("clientListener.OnStop", "clientListener.OnStop");

    thread1.Abort();

    thread2.Abort();

    base.OnStop();

    }

    private void ListenToServer()

    {

    EventLog.WriteEntry("clientListener.ListenToServer", "ListenToServer starting");

    IPAddress localhostAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];

    Int32 iPort = 63000;

    TcpListener tcpList = new TcpListener(localhostAddress, iPort);

    try

    {

    tcpList.Start();

    while (tcpList.Pending() == false)

    Thread.Sleep(1000); //every 1 second

    TcpClient tcpClient = tcpList.AcceptTcpClient();

    NetworkStream ns = tcpClient.GetStream();

    StreamReader sr = new StreamReader(ns);

    String sMessage = sr.ReadLine();

    StreamWriter sw = new StreamWriter(ns);

    sw.WriteLine("###OK### From Server");

    sw.Flush();

    sr.Close();

    sw.Close();

    ns.Close();

    tcpClient.Close();

    tcpList.Stop();

    switch (sMessage)

    {

    case "###SHUTDOWN###":

    WindowsController.ExitWindows(RestartOptions.ShutDown, false);

    break;

    case "###REBOOT###":

    WindowsController.ExitWindows(RestartOptions.Reboot, false);

    break;

    case "###LOGOFF###":

    WindowsController.ExitWindows(RestartOptions.LogOff, false);

    break;

    }

    }

    catch (ThreadAbortException)

    {

    EventLog.WriteEntry("clientListener.ListenToServer", "Thread Abort Exception");

    }

    catch (Exception ex)

    {

    EventLog.WriteEntry("clientListener.ListenToServer", ex.Message);

    }

    EventLog.WriteEntry("clientListener.ListenToServer", "ListenToServer exiting");

    }

    private void UpdateDatabase()

    {

    EventLog.WriteEntry("clientListener.InitialConnection", "InitialConneciton starting");

    //initial connection to database

    MySqlConnection MyConnection = new MySqlConnection("server=admin1;username=root;password=as8508;database=timeout");

    MySqlCommand MyCommand = null;

    MySqlDataReader dr = null;

    try

    {

    //check for values in HostName, ipaddress, and iFlag

    //if they do not exist add them else continue

    String sHostName = Dns.GetHostName();

    MyCommand = new MySqlCommand("SELECT * FROM complist WHERE HostName='" + sHostName + "'", MyConnection);

    MyConnection.Open();

    dr = MyCommand.ExecuteReader();

    if (!dr.Read())

    {

    String sIPAdd = Dns.GetHostEntry(sHostName).AddressList[0].ToString();

    MyCommand = new MySqlCommand("INSERT INTO complist VALUES('" + sHostName + "','" + sIPAdd + "',0)", MyConnection);

    dr.Close();

    dr = MyCommand.ExecuteReader();

    }

    dr.Close();

    }

    catch (ThreadAbortException)

    {

    EventLog.WriteEntry("clientListener.InitialConnection", "Aborted");

    }

    catch (MySqlException MyErr)

    {

    EventLog.WriteEntry("clientListener.InitialConnection", MyErr.Number + " - " + MyErr.Message);

    }

    MyConnection.Close();

    EventLog.WriteEntry("clientListener.InitialConnection", "InitialConneciton exiting");

    }

    static void Main()

    {

    EventLog.WriteEntry("clientListener.Main", "clientListener Main starting");

    ServiceBase.Run(new Client());

    EventLog.WriteEntry("clientListener.Main", "clientListener Main exiting");

    }

    }

    [RunInstaller(true)]

    public class ClientInstaller : Installer

    {

    /// <summary>

    /// Public Constructor for WindowsServiceInstaller - Put all of your Initialization code here.

    /// </summary>

    public ClientInstaller()

    {

    ServiceProcessInstaller serviceProcessInstaller = new ServiceProcessInstaller();

    ServiceInstaller serviceInstaller = new ServiceInstaller();

    serviceProcessInstaller.Account = ServiceAccount.LocalSystem;

    serviceProcessInstaller.Username = null;

    serviceProcessInstaller.Password = null;

    serviceInstaller.DisplayName = "clientListener";

    serviceInstaller.Description = "waits for the following commands shutdown, reboot, or logoff and then performs them";

    serviceInstaller.StartType = ServiceStartMode.Automatic;

    //This must be identical to the WindowsService.ServiceBase name set in the Client class constructor

    serviceInstaller.ServiceName = "clientListener";

    this.Installers.Add(serviceProcessInstaller);

    this.Installers.Add(serviceInstaller);

    }

    }

    }


  • AbelMorelos

    Hi,

    I havnt worked with MySql much so i cant give you suggestions on that but you can check the connection string if it requires some additional parameters like port etc... ref: http://www.connectionstrings.com/ carrier=mysql

    Also, if you have other machine accessible then try to run on that using test/default database

    Also, instead of passing hostname as user/pass, try using default credentials for the database instead of other database users

    Check it if it works, and please inform me...

    Also, check in each log entry to identify other exceptions you are getting if any, before we move ahead each exception must be resolved.

    HTH,



  • tcplistener and winxp service