简体   繁体   English

C#重新启动TCP服务器

[英]c# restart a tcp server

I have the following c# form application which is a tcp server which handles incoming file request. 我有以下c#表单应用程序,它是一个处理传入文件请求的tcp服务器。 I would like to restart the thread when there is some exception handling or via manual button press. 我想在进行一些异常处理或通过手动按下按钮时重新启动线程。 The problem is that once i invoke the thread Abort() function, the whole application freezes. 问题是,一旦我调用线程Abort()函数,整个应用程序就会冻结。

I do understand there are other methods in doing this more gracefully. 我确实了解,还有其他一些方法可以更优雅地执行此操作。 How do I do then? 那我该怎么办? Thanks! 谢谢!

  public partial class Form1 : Form
{
    Thread t2;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
         t2 = new Thread(delegate()
        {
            startServer();
        });
        t2.Start();

    }

    private void restartServer()
    {
        t2.Abort();
        t2.Start();
    }

    private void startServer()
    {

            // Listen on port 1234      
        TcpListener tcpListener = new TcpListener(IPAddress.Any, 1234);

            tcpListener.Start();

            Console.WriteLine("Server started");
            textBox1.Invoke((MethodInvoker)(() => textBox1.Text += "server started"));
            //Infinite loop to connect to new clients      
            while (true)
            {
                // Accept a TcpClient      
                TcpClient tcpClient = tcpListener.AcceptTcpClient();

                //textBox1.Text += "Connected to client\n";
                textBox1.Invoke((MethodInvoker)(() => textBox1.Text += "Connected to client"));
                StreamReader reader = new StreamReader(tcpClient.GetStream());

                // The first message from the client is the file size      
                string cmdFileSize = reader.ReadLine();

                // The first message from the client is the filename      
                string cmdFileName = reader.ReadLine();

                int length = Convert.ToInt32(cmdFileSize);
                byte[] buffer = new byte[length];
                int received = 0;
                int read = 0;
                int size = 1024;
                int remaining = 0;

                // Read bytes from the client using the length sent from the client      
                while (received < length)
                {
                    remaining = length - received;
                    if (remaining < size)
                    {
                        size = remaining;
                    }

                    read = tcpClient.GetStream().Read(buffer, received, size);
                    received += read;
                }

                // Save the file using the filename sent by the client      
                String fileName = Path.GetFileName(cmdFileName);
                String path1 = Path.GetDirectoryName(Application.ExecutablePath) + "\\ReceivedLogs\\" + fileName;
                Console.WriteLine("path:"+path1);
                using (FileStream fStream = new FileStream(path1, FileMode.Create))
                {
                    fStream.Write(buffer, 0, buffer.Length);
                    fStream.Flush();
                    fStream.Close();
                }
                textBox1.Invoke((MethodInvoker)(() => textBox1.Text += "File received and saved in " + Environment.CurrentDirectory + "\n"));
               // textBox1.Text += ("File received and saved in " + Environment.CurrentDirectory+"\n");
            }
        }

    private void label1_Click(object sender, EventArgs e)
    {

    }

    private void textBox1_TextChanged(object sender, EventArgs e)
    {

    }

    private void button1_Click(object sender, EventArgs e)
    {
        restartServer();
    }


    }
}

Edit 1 :Changed all invoke to 'BeginInvoke' and the freeze still persist. 编辑1 :将所有调用更改为“ BeginInvoke”,并且冻结仍然持续。

Thanks to Wolf5 and his link, Thread.Abort() method freezes . 感谢Wolf5及其链接, Thread.Abort()方法冻结了 By stopping all services in the thread and creating boolean works. 通过停止线程中的所有服务并创建布尔工作。

    private void restartServer()
    {
      try { 
        try {
            check = false;
            tcpListener.Stop();
            textBox1.BeginInvoke((MethodInvoker)(() => textBox1.AppendText("Server stopping..\r\n")));
            t2.Abort();
            check = true;
            startThread();
        }
        catch(ThreadAbortException){

        }
         }  
        catch(ThreadAbortException)
      {
          Thread.ResetAbort();
      }
    }

So the point is to let the CLR know that it is safe to abort by stopping all running services before aborting. 因此,要点是让CLR知道通过中止所有正在运行的服务来中止是安全的 Thanks! 谢谢! :D :D

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM