【问题标题】:c# TCP Server Client Threading Issiesc# TCP 服务器客户端线程问题
【发布时间】:2015-08-29 23:13:12
【问题描述】:

问题来了, 我有以下场景编码。

  1. 在线程 A 中运行的 TCP 侦听器连接到客户端 1
  2. 在线程 B 中运行的第二个 TCP 侦听器连接到多个客户端,每个客户端都在不同的线程中。我的意思是只要客户 在线程 B 中接受,创建一个不同的线程以供进一步 处理等待从“TCP”获取数据的客户端 监听器 B" 在 while 循环中

我想做什么以及我面临的问题是,

我想将客户端 1 从线程 1 收到的数据传递给线程 2 中的客户端。

我认为正在发生的事情

由于我在线程 1 中从客户端 1 获取数据时处于线程 1 中,因此当我尝试在线程 2 中向客户端发送数据时,我总是得到连接错误。

这是线程问题吗?

我该如何克服它的问题?

编辑

这是一个窗体应用程序

两个 TCP 侦听器都在同一个应用程序中运行。

我正在维护一个连接到 TCP 侦听器 B 的 TcpClients 列表,当我从线程 A 获取一些数据时,我从我维护的该列表中获取 TCP 客户端并尝试发送数据,但不能作为连接状态变成假的。

【问题讨论】:

  • 不使用线程而是使用异步套接字会更简单。对于这种数据传输,您可以只使用事件。
  • 你想怎么沟通?过一个港口?或者这一切都在一个内存空间中?
  • @Henk 这一切都在一个内存空间中
  • @sami 我尝试使用acceptclient 和beginread 回调,但由于某种原因,当我调试时,接收函数被触发,但是当我尝试不调试时,接收回调永远不会被触发!! !!
  • 好吧,没有代码我们还能说什么?该图非常有用。一般来说,套接字编程非常困难,并且在没有等待的情况下使用异步 IO 会增加很多问题。

标签: c# multithreading tcpclient tcp-ip tcplistener


【解决方案1】:

我也遇到了同样的问题,所以我使用后台工作程序而不是线程来处理客户端。这是从我的项目中提取的代码:

 private static void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        listener.Start();
        while (!bw.CancellationPending)
        {
            TcpClient client = listener.AcceptTcpClient();
            ThreadPool.QueueUserWorkItem(ThreadProc, client);
        }
        listener.Stop();
    }

在 ThreadProc 中它只是处理每个客户端

private static void ThreadProc(object state)
    {
        var client = (TcpClient)state;
        clientsList.Add(client);
        handleClient hclient = new handleClient();
        hclient.startClient(client); //Do whatever with your client here
    }

为了广播信息我这样做了

public static void broadcast(byte[] msg, string uName)
    {
        foreach (TcpClient Item in clientsList)
        {
            if (Item != null)
            {
                try
                {
                    TcpClient broadcastSocket;
                    broadcastSocket = Item;
                    NetworkStream broadcastStream = broadcastSocket.GetStream();
                    Byte[] broadcastBytes = null;

                    broadcastBytes = msg;

                    Debug.WriteLine("Send Data to everyone from " + uName);
                    broadcastStream.Write(broadcastBytes, 0, broadcastBytes.Length);
                    broadcastStream.Flush();
                }
                catch (Exception)
                {
                    //Handle exceptions ....
                }

            }
        }
    }

我希望他的帮助。您可以在 https://github.com/hrkrx/MontagsmalerVS 查看完成的项目,示例来自 HostController.cs

【讨论】:

    【解决方案2】:

    正如我所见,您正在使用线程和 Winform 以及套接字服务器和套接字客户端,这可能会使该套接字被阻塞。

    尝试使用单个线程来处理所有 TCPListeners 和 TCPClients,使用有助于避免套接字阻塞的异步方法:

    • 对于 TcpListener 使用方法:AcceptSocketAsync
    • 对于 TcpClients,使用 NetworkStream 来使用 BeginRead 和 BeginWrite。在这个answer 中,我展示了我是如何使用它们的。

    【讨论】:

      猜你喜欢
      • 2019-04-18
      • 2020-07-15
      • 2014-03-04
      • 1970-01-01
      • 2012-07-04
      • 1970-01-01
      • 2016-09-26
      • 1970-01-01
      • 2022-01-22
      相关资源
      最近更新 更多