如何在TcpListener线程和主线程之间传输数据?

时间:2012-06-13 06:14:33

标签: c# tcp buffer tcplistener

我有一个基于C#的套接字通信线程。服务器中的缓冲区是1024字节,现在我需要一种在通信线程和通信线程之间传输数据的方法。主线程。我怎样才能做到这一点?我是否需要打开一个新的缓冲区,然后将数据复制到它?或者我可以从客户端或服务器的缓冲区中获取数据吗?

private void ServerResponse()
    {
        byte[] buff = new byte[1024];
        string msg;
        int len;
        try
        {
            if (!Stream.CanRead)
            {
                return;
            }

            stopFlag = false;
            while (!stopFlag)
            {
              len = Stream.Read(buff, 0, buff.Length);
                if (len < 1                    
                  {
                    Thread.Sleep(200);
                    continue;
               }
            }
       }
 }

以上是服务器用于从客户端获取数据的功能。我的问题是我可以将此函数获取的数据发送到主线程,或者我应该在上面函数的定义之外设置一个新缓冲区并将数据复制到它。

3 个答案:

答案 0 :(得分:0)

如果你的主线程通常被称为UI线程,那么这个讨论会给你一些想法:how to update GUI with background worker

答案 1 :(得分:0)

您需要将收到的消息写入主线程可访问的缓冲区。您可以通过为每个收到的消息创建一个新缓冲区(一个字节数组)并将该缓冲区添加到ConcurrentQueue<>来实现这一点,这对多线程读取器/写入器方案很有用。这样,您的侦听线程会将收到的消息写入队列,并且您的主线程可以以线程安全的方式从同一队列中读取消息。

根据您的使用情况,您可能能够构建更有意义的对象(例如请求对象)并将其传递给主线程而不是传递字节。

编辑:基于评论

假设您在公共范围内定义了ConcurrentQueue<byte[]>

public ConcurrentQueue<byte[]> ReceivedMsgs = new ConcurrentQueue<byte[]>();

你可以在监听器线程中做这样的事情(在将消息字节读入buff之后):

var msg = new byte[len];
Buffer.BlockCopy(buff, 0, msg, 0, len);
this.ReceivedMsgs.Enqueue(msg);

然后在主线程中,您可以将消息出列队列:

byte[] msg;
if (server.ReceivedMsgs.TryDequeue(out msg))
{
    //use msg
}

答案 2 :(得分:0)

取决于如何将数据传输到主线程。如果以字节为单位,则直接调用以下代码。如果没有,首先将数据转换为可呈现的形式,然后调用代码:

// Place this on the main thread's class initialization.
private static readonly SynchronizationContext _syncContext =
    SynchronizationContext.Current;

// Then your worked thread will be like this:
if (len < 1)                  
{
    Thread.Sleep(200);
    continue;
}
else
{
    _syncContext.Post(o => MainThreadClass.ReceiveData((byte[])buff), buff);
}