Adi
Adi

Reputation: 1455

TCP/IP Socket is not reading data from machine when running as Windows Service in c#

I have a simple TCP/IP program to read data from a machine and write it into text file. I want to run it as Windows Service so that data gets written into text file continuously with out any intervention. Now when I try to run the program under debug mode of Visual Studio, it is reading the data from the machine and saving into text file, but as soon as I add it as Windows Service and try to start the service, it is giving following error message..

windows service could not start the service on the local computer

error:1053 The service did not respond to the start or the control request in a timely  fashion 

Here is my main applications code..

static void Main()
    {

        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] 
        { 
            new Service1() 
        };
        ServiceBase.Run(ServicesToRun);

    }

Here is my code to communicate to the machine using TCP/IP and read/write data into text file..

        protected override void OnStart(string[] args)
    {
        ipaddress = "";
        int port = int.Parse("");
        textfileSaveLocation = "";

        byte[] data = new byte[1024];
        string stringData;

        IPAddress ipadd = IPAddress.Parse(ipaddress);
        IPEndPoint ipend = new IPEndPoint(ipadd, port);
        Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        sock.NoDelay = false;
        try
        {
            sock.Connect(ipend);

        }
        catch (Exception dfg)
        {    
            return;
        }
        try
        {
            buf = String.Format("SMDR", "PCCSMDR");
            bBuf = Encoding.ASCII.GetBytes(buf);
            sock.Send(bBuf);

            while (true)
            {
                data = new byte[1024];
                int recv = sock.Receive(data);
                stringData = Encoding.ASCII.GetString(data, 0, recv);

                string df = "";
                try
                {
                    FileStream dr = new FileStream(textfileSaveLocation, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite);
                    StreamReader fg = new StreamReader(dr);
                    df = fg.ReadToEnd();
                    fg.Dispose();
                    dr.Dispose();
                }
                catch (Exception dfjdfs)
                {
                }

                try
                {
                    FileStream cd = new FileStream(textfileSaveLocation, FileMode.Create);
                    StreamWriter cdf = new StreamWriter(cd);
                    cdf.WriteLine(df);
                    cdf.WriteLine(stringData);
                    cdf.Dispose();
                    cd.Dispose();
                }
                catch (Exception hgy)
                {
                }
            }
            sock.Shutdown(SocketShutdown.Both);
            sock.Close();
        }
        catch (Exception DFGFD)
        {
        }
    }

My only aim with this program is to run it as Windows Service through installer and start the service. Once the service is started, it should read the data from the given ip and port of the machine and save it into text file. Also I need this service to continuously monitor for the data from the machine and once new data comes to the machine, it should read and write into the text file.

Do I need to implement Multi-threading in the program?

Upvotes: 1

Views: 695

Answers (2)

Matt Davis
Matt Davis

Reputation: 46044

The system expects the OnStart method to return in a timely fashion (~30 seconds), so long-running tasks like monitoring for data need to be moved to another thread. This can be as simple as:

private System.Threading.Thread _thread;
protected override void OnStart(string[] args)
{
    _thread = new Thread(DoWork);
    _thread.Start();
}

private void DoWork()
{
    // create and monitor socket here...
}

Note that while your while (true) loop is sufficient to keep the thread running, it makes it difficult to stop it when the service stops. For this, I use a ManualResetEvent like so.

using System.Threading;
private ManualResetEvent _shutdownEvent = new ManualResetEvent(false);

private void DoWork()
{
    // initialize socket and file

    // thread loop
    while (!_shutdownEvent.Wait(0))
    {
        // read socket, write to file
    }

    // close socket and file
}

protected override void OnStop()
{
    _shutdownEvent.Set();
    _thread.Join();  // wait for thread to stop
}

Upvotes: 2

omer schleifer
omer schleifer

Reputation: 3935

I agree with Matt's answer.

Also, In general , it is good to add an option to debug your service, here is an example:

     protected override void OnStart(string[] args)
        {         
                bool launchDebugger = false;
                if (args.Count() > 0)
                {
                    launchDebugger = args[0].ToLower() == "debug";
                }


                if (launchDebugger)
                {                   
                   Debugger.Launch();
                }    
} 

When you run the service with an argument: "debug", it will trigger a fake exception, allowing you to debug the service with visual studio.

Upvotes: 1

Related Questions