简体   繁体   English

螺纹Socket.Send()

[英]Threaded Socket.Send()

I have 2 threads running simultaneously and each is writing to the socket.Send() stream, 我有2个线程同时运行,每个线程都正在写入socket.Send()流,

   While (soc.Connected)
        {


                byte[] byData = new byte[2];
                byData = System.Text.Encoding.ASCII.GetBytes("A");
                soc.Send(BitConverter.GetBytes(byData.Length));
                soc.Send(byData);


        }

The other thread uses the exact same code, except it's sending "1" instead of "A". 另一个线程使用完全相同的代码,除了发送“ 1”而不是“ A”。

How will the data at the other end look like? 另一端的数据如何? Will it be either a stream of AAAAAAAA or 111111111s or randomly mixed like A1A1111AAAA1 ? 它是AAAAAAAA还是111111111s的流,还是像A1A1111AAAA1这样的随机混合流?

Should I avoid this way of sending entirely and block the sending until the other thread finishes? 我是否应该避免完全发送这种方式,并在其他线程完成之前阻止发送?

Should I avoid this way of sending entirely and block the sending until the other thread finishes? 我是否应该避免完全发送这种方式,并在其他线程完成之前阻止发送?

Yes and no, you should avoid this entirely but it is not necessary to block sending till the other thread finishes. 是的,不是,您应该完全避免这种情况,但是没有必要在其他线程完成之前阻止发送。

What you could do is have a 3rd thread who's responsibility is to send data and your two threads who need to send data put their data on to a thread safe queue. 您可以做的是让第三个线程负责发送数据,而需要发送数据的两个线程将其数据放入线程安全队列中。 Then the sending thread would dequeue the work to be done and send it out on the wire. 然后,发送线程将使要完成的工作出队,并通过网络将其发送出去。

const int MAX_QUEUE_LENGTH = 10;
private BlockingCollection<MyMessageContainer> messageQueue = new BlockingCollection<MyMessageContainer>(new ConcurrentQueue<MyMessageContainer>(), MAX_QUEUE_LENGTH);

void ProcessMessages()
{
    foreach (var message in messageQueue.GetConsumingEnumerable())
    {
        if(soc.Connected == false)
            break;

        soc.Send(message.ToPaylod());
    }
}

void GenerateMessageOne()
{
    while(true)
    {
        messageQueue.Add(new MyMessageContainer("A"));
    }
}

void GenerateMessageTwo()
{
    while(true)
    {
        messageQueue.Add(new MyMessageContainer("1"));
    }
}


class MyMessageContainer
{
     public MyMessageContainer(string message)
     {
          _message = message;
     }

     private string _message;

     public byte[] ToPayload()
     {
         var lengthBytes = BitConverter.GetBytes(byData.Length);
         return lengthBytes.Concat(() => System.Text.Encoding.ASCII.GetBytes(_message)).ToArray();
     }
}

The above code will let both threads queue work at the same time without blocking till the queue reaches a length of MAX_QUEUE_LENGTH , once there calling messageQueue.Add( will now start blocking till the sending thread has had a chance to clear up some room, once room has been made it will unblock one of the functions and let it continue. 上面的代码将使两个线程同时工作,而不会阻塞,直到队列的长度达到MAX_QUEUE_LENGTH为止,一旦调用messageQueue.Add(现在将开始阻塞,直到发送线程有机会清理一些空间为止腾出空间后,它将取消阻止其中一项功能,并使其继续运行。

If you want randomly-sequenced output, the easiest solution is to simply put a lock around the line that actually writes to the socket. 如果要随机排序的输出,最简单的解决方案是在实际写入套接字的行周围放一个锁。 I would also recommend adding a call to Thread.Sleep for fairness, though that is somewhat optional. 为了公平起见,我还建议添加对Thread.Sleep的调用,尽管这是可选的。

While (soc.Connected)
{
    byte[] byData = new byte[2];
    byData = System.Text.Encoding.ASCII.GetBytes("A");
    lock(soc) 
    {
        soc.Send(BitConverter.GetBytes(byData.Length));
        soc.Send(byData);
    }
    Thread.Sleep(0);
}

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

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