在C#中实现套接字监听器的最佳方法

8
我已经搜索过答案,但找不到类似的内容...
我对C#还比较陌生。我需要使用WinForms在C#中创建一个程序。它基本上有两个组成部分:UI和一个需要永久侦听socket TCP端口的进程。如果收到任何消息,则需要触发事件或类似的东西,以便可以更新UI。
问题:如何实现一个需要在程序运行时始终监听的进程?
然后,当我接收到一条消息时,如何通知UI需要进行更新?
谢谢!
4个回答

11

您可以使用一个 TcpListener 在另一个线程上等待传入的连接。每次收到新连接时,创建一个新线程来处理它。使用 Control.Invoke 从非UI线程更新UI。这是一个简短的示例:

public MainForm()
{
    InitializeComponents();
    StartListener();
}

private TcpListener _listener;
private Thread _listenerThread;

private void StartListener()
{
    _listenerThread = new Thread(RunListener);
    _listenerThread.Start();
}

private void RunListener()
{
    _listener = new TcpListener(IPAddress.Any, 8080);
    _listener.Start();
    while(true)
    {
        TcpClient client = _listener.AcceptTcpClient();
        this.Invoke(
            new Action(
                () =>
                {
                    textBoxLog.Text += string.Format("\nNew connection from {0}", client.Client.RemoteEndPoint);
                }
            ));;
        ThreadPool.QueueUserWorkItem(ProcessClient, client);
    }
}

private void ProcessClient(object state)
{
    TcpClient client = state as TcpClient;
    // Do something with client
    // ...
}

我为什么被踩了?请评论!我乐于接受批评,但如果我不知道我的回答有什么问题,那就没有建设性... - Thomas Levesque
这只是个表面问题,但我认为在 this.Invoke(...);; 后面多了一个分号。(只是为了澄清,这不是你被踩的原因,至少不是我踩的) - Manu

1
你可以使用 TcpListener 类。文档中有一个示例。

我认为他们更希望得到一个架构方面的答案......看起来他们不确定如何将TcpListener与事件驱动程序集成。 - Polaris878

1
在启动时,您可以生成(创建)一个新的线程,该线程在无限循环中监听新消息。一旦收到消息,线程就可以更新某些共享资源(设置标志)。当然,如果您使用同步队列传输消息,可以使此过程更加复杂。或通过WCF(尽管这似乎对您的目的来说有些过度设计)。

1

这可能不是最好的方法,但应该可以工作...

当程序启动时,您可以在新线程中启动TCP监听器代码... 这样,当UI执行其他任务时,TCP代码就会监听。当TCP线程发生某些事情时,它将通过某种事件或事件队列向UI线程发出信号。

现在,在接收到某些内容时更新WinForms对象方面,我认为只有创建WinForms控件的线程才能更新控件。因此,您还需要考虑这一点。

这也是我以前曾经遇到过的问题... 在我的当前项目中,我做了上述操作... 但是需要进行相当多的线程同步才能使其正常工作。


2
从另一个线程更新UI非常容易:您只需要使用Control.Invoke方法,通过传递更新UI的委托即可。 - Thomas Levesque

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接