C# Winform : Ошибка при попытке запустить клиентское приложение TCP

#c# #visual-studio #function #winforms #tcpclient

Вопрос:

У меня есть приложение Winform на C#, которое пытается запустить сервер узлов.

Однако код для этого написан в другом файле cs, Class1.cs, а не в самой форме.cs. Мне нужно хранить это отдельно в разных файлах. Ниже приведен мой файл Class1.cs:

 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();
            }
        }
    
    }
 

Теперь, когда я вызываю функцию из своего файла Form.cs, как показано ниже:

 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();
        }
 

я начинаю System.NullReferenceException NetworkStream nwStream = client.GetStream(); .
поскольку ни один клиент не подключен. Но для того, чтобы достичь этого, сервер узлов должен быть запущен первым правильно ?

Мне удалось добиться этого в консольном приложении, где я вызвал NodeServer() метод перед client.Connect() методом в основной функции

  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)
                {
                   
                }                
            }
        }
 

Как я могу повторить то же самое в приложении Winform для Form_load метода (где методы определены в самом Class1.cs). Является Form_Load ли правильным событием для вызова NodeServer() метода?

Ответ №1:

Вы не должны смешивать прямую инициализацию члена и логику конструктора. Это затрудняет понимание потока кода.

Эта строка объявляет переменную и инициализирует ее:

 NetworkStream nwStream = client.GetStream();
 

Это эквивалентно изменению приведенной выше строки на:

 NetworkStream nwStream;
 

и добавив следующее в качестве первой строки конструктора:

 nwStream = client.GetStream();
 

Это делает очевидным, что клиент не инициализирован.

В вашем случае просто переместите код подключения в отдельный метод:

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

Я также предлагаю убрать static это из декларации client .

Комментарии:

1. Хорошо, но где я должен объявить и вызвать метод Connect ()?. Объявите в Form.cs и вызовите его там или объявите его в Class1.cs и вызовите его в Form.cs ? Также в каком файле NetworkStream nwStream; amp; nwStream = клиент. GetStream(); должен быть определен ? Форма 1.cs или класс 1.cs

2. Подключение должно быть в классе NodeApp и вызываться из формы (с помощью кнопки или в методе Onload). Объявление NetwokStream в классе 1 является правильным.