【问题标题】:How would I constant listen on a port with a GUI?我如何使用 GUI 持续监听端口?
【发布时间】:2012-03-20 22:32:54
【问题描述】:

我正在尝试学习 TCP 服务器/客户端交互。我想知道如何一直使用 GUI 监听端口。目前我正在使用此代码:

    private void Form1_Load(object sender, EventArgs e)
    {
        CreateServer();
    }

    void CreateServer()
    {
        TcpListener tcp = new TcpListener(25565);
        tcp.Start();

        Thread t = new Thread(() =>
        {

            while (true)
            {
                var tcpClient = tcp.AcceptTcpClient();

                ThreadPool.QueueUserWorkItem((_) =>
                {
                    Socket s = tcp.AcceptSocket();
                    
                    console.Invoke((MethodInvoker)delegate { console.Text += "Connection esatblished: " + s.RemoteEndPoint + Environment.NewLine; });

                    byte[] b = new byte[100];
                    int k = s.Receive(b);


                    for (int i = 0; i < k; i++)
                    {
                        console.Text += Convert.ToChar(b[i]);
                        incoming += Convert.ToChar(b[i]);
                    }

                    MessageBox.Show(incoming);

                    console.Invoke((MethodInvoker)delegate { console.Text += incoming + Environment.NewLine; });

                    list.Invoke((MethodInvoker)delegate { list.Items.Add(incoming); });

                    ASCIIEncoding asen = new ASCIIEncoding();
                    s.Send(asen.GetBytes("\n"));

                    tcpClient.Close();
                }, null);
            }
        });
        t.IsBackground = true;
        t.Start();
    }

任何帮助将不胜感激。

【问题讨论】:

    标签: c# .net multithreading tcp


    【解决方案1】:

    简短回答 - 在单独的线程/任务 (TPL) 中运行 TCP 侦听器。 对于完整的工作解决方案,您还必须使用取决于您使用的框架的特殊技术将 UI 的任何更改从单独的线程发送到主线程,我的意思是 WPF/WinForms/whatever。

    下面的代码对我来说很好。之前阅读 TODO 部分。

    待办事项:

    • 添加到表单Textbox、ListBox、Button,公开:

      public System.Windows.Forms.TextBox console;
      public System.Windows.Forms.ListBox incommingMessages;
      private System.Windows.Forms.Button sendSampleDataButton;
      

    入口点:

    private static Form1 form;
    
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
    
        form = new Form1();
        form.Load += OnFormLoad;
        Application.Run(form);
    }
    
    private static void OnFormLoad(object sender, EventArgs e)
    {
        CreateServer();
    }
    

    服务器:

    private static void CreateServer()
    {
        var tcp = new TcpListener(IPAddress.Any, 25565);
        tcp.Start();
    
        var listeningThread = new Thread(() =>
        {
            while (true)
            {
                var tcpClient = tcp.AcceptTcpClient();
                ThreadPool.QueueUserWorkItem(param =>                                                            
                {                        
                    NetworkStream stream = tcpClient.GetStream();
                    string incomming;                        
                    byte[] bytes = new byte[1024];
                    int i = stream.Read(bytes, 0, bytes.Length);                                                
                    incomming = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
                    form.console.Invoke(
                    (MethodInvoker)delegate
                        {
                            form.console.Text += String.Format(
                                "{0} Connection esatblished: {1}{2}", 
                                DateTime.Now,
                                tcpClient.Client.RemoteEndPoint,
                                Environment.NewLine);
                        });
    
                    MessageBox.Show(String.Format("Received: {0}", incomming));
                    form.incommingMessages.Invoke((MethodInvoker)(() => form.incommingMessages.Items.Add(incomming)));
                    tcpClient.Close();
                }, null);
            }
        });
    
        listeningThread.IsBackground = true;
        listeningThread.Start();
    }
    

    客户

    private void button1_Click(object sender, EventArgs e)
    {
        Connect("localhost", "hello localhost " + Guid.NewGuid());
    }
    
    static void Connect(String server, String message)
    {
        try
        {               
            Int32 port = 25565;
            TcpClient client = new TcpClient(server, port);             
            Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
            NetworkStream stream = client.GetStream();
    
            // Send the message to the connected TcpServer. 
            stream.Write(data, 0, data.Length);                                
            stream.Close();
            client.Close();
        }
        catch (ArgumentNullException e)
        {
            Debug.WriteLine("ArgumentNullException: {0}", e);
        }
        catch (SocketException e)
        {
            Debug.WriteLine("SocketException: {0}", e);
        }          
    }
    

    截图:

    【讨论】:

    • 我没有看到对 tpl 的任何引用。你在用 tpl 吗?
    【解决方案2】:

    创建一个线程,开始监听它并且不要停止服务器

    void CreateServer()
    {
        TcpListener tcp = new TcpListener(25565);
        tcp.Start();
    
        Thread t = new Thread(()=>
        {
            while (true)
            {
                var tcpClient = tcp.AcceptTcpClient();
                ThreadPool.QueueUserWorkItem((_) =>
                {
                    //Your server codes handling client's request.
                    //Don't access UI control directly here
                    //Use "Invoke" instead. 
                    tcpClient.Close();
                },null);
            }
        });
        t.IsBackground = true;
        t.Start();
    }
    

    【讨论】:

    • 嘿,我更新了我的代码,你能看一下吗?它似乎不起作用,可能是因为我是这个领域的新手。
    • It doesn't seem to be working 什么不起作用?你得到什么错误?
    【解决方案3】:

    您可以使用线程方法(如其他答案所述)或使用asynchronous sockets,在我看来这更好。更棒的是,你可以使用SocketAsyncEventArgs 提出的异步模型。 异步套接字将受益于使用completion ports

    【讨论】:

      【解决方案4】:

      这是 mdsn 上的一个很好的例子:Asynchronous server socket example

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-07-06
        • 2021-12-16
        • 1970-01-01
        • 1970-01-01
        • 2016-01-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多