Search code examples
c#visual-studiofunctionwinformstcpclient

C# Winform : Error while trying to launch TCP client application


I have a C# Winform application trying to launch a node server.

However the code for this is written in a different cs file, Class1.cs rather than in Form.cs itself. I need to keep this separated in different files. Below is my Class1.cs file:

using System.Net.Sockets;
namespace NodeApp
    {
        class Class1
        {
            static string HOST = "localhost";
            static int PORT = 9999;
            static TcpClient client;
            NetworkStream nwStream = client.GetStream();
           
            public void NodeServer()
            {
                string strCmdText;
                strCmdText = "/C node C:\\Desktop\\Test.js";
                Process process = new Process();
                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.FileName = "cmd.exe";
                startInfo.Arguments = strCmdText;
                process.StartInfo = startInfo;
                process.Start();
            }
        }
    
    }

Now when I call the function from my Form.cs file, like below:

using System.Net.Sockets;
namespace NodeApp
{
    public partial class Form1 : Form
    {

        Class1 cl = new Class1();
        
        public Form1()
        {
            InitializeComponent();
            
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            cl.NodeServer();
        }

am getting System.NullReferenceException at NetworkStream nwStream = client.GetStream();. as no client is connected. But in-order to achieve that, the Node server should be running first correct ?

I was able to achieve this in a console based application where I called the NodeServer() method before the client.Connect() method in the Main function

 static void Main(string[] args)

        {
            NodeSever();
            Thread.Sleep(1500);
            Console.WriteLine("Connecting to Node Server....");
            bool connected = false;
            client = new TcpClient();
            while(!connected)
            {
                Thread.Sleep(2000);
                try
                { 
                    client.Connect(HOST, PORT);
                    connected = true;
                }
                catch (SocketException e)
                {
                   
                }                
            }
        }

How can I replicate the same in a Winform application on Form_load method (where methods are defined in Class1.cs itself). Is Form_Load the right event to call the NodeServer() method?


Solution

  • You should not mix direct member initialisation and constructor logic. This makes it hard to understand the code flow.

    This line declares a variable and initializes it:

    NetworkStream nwStream = client.GetStream();
    

    It is equivalent to changing the above line to:

    NetworkStream nwStream;
    

    and adding the following as the first line of the constructor:

    nwStream = client.GetStream();
    

    This makes it obvious that the client is not initialized.

    In your case, just move the connection code to a separate method:

         public void Connect()
         {
                client = new TcpClient();
                while(!connected)
                {
                    Thread.Sleep(2000);
                    try
                    { 
                        client.Connect(HOST, PORT);
                        connected = true;
                    }
                    catch (SocketException e)
                    {
                       
                    }                
                }
         }
    

    I also suggest to remove the static from the declaration of client.