用的SocketAsyncEventArgs发送的订单数据 [英] Sending data in order with SocketAsyncEventArgs

查看:630
本文介绍了用的SocketAsyncEventArgs发送的订单数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

发送数据时,这个问题是,我是允许使用多的SocketAsyncEventArgs发送数据,但第一个数据包没有第二个数据包之前完全发送,这是因为我有,所以我本来有一个竞争条件如果数据不适合在缓冲区它循环,直到所有的数据被发送,并且所述第一分组比其小的第二分组较大,所以第二分组被发送和达到给客户端的第一个包之前。

I originally had a race condition when sending data, the issue was that I was allowing multiple SocketAsyncEventArgs to be used to send data, but the first packet didn't send fully before the 2nd packet, this is because I have it so if the data doesn't fit in the buffer it loops until all the data is sent, and the first packet was larger than the second packet which is tiny, so the second packet was being sent and reached to the client before the first packet.

我通过分配1 SocketAyncEventArgs一个开放的连接,以用于发送数据的解决了这一点,并用一个信号量来限制访问它,使让SocketAsyncEventArgs回调一旦它完成。

I have solved this by assigning 1 SocketAyncEventArgs to an open connection to be used for sending data and used a Semaphore to limit the access to it, and make the SocketAsyncEventArgs call back once it completed.

现在这工作得很好,因为所有的数据发送,回调时,其完整的准备下一次发送。这样做的问题是,其造成阻塞时,我想随机发送数据到打开的连接,当有大量数据发送它要阻止我的线程。

Now this works fine because all data is sent, calls back when its complete ready for the next send. The issue with this is, its causing blocking when I want to send data randomly to the open connection, and when there is a lot of data sending its going to block my threads.

我要寻找一个工作围绕这一点,我认为有,当被请求数据发送队列,它只是增加了数据包队列,然后1的SocketAsyncEventArgs只是循环来发送数据。

I am looking for a work around to this, I thought of having a Queue which when data is requested to be sent, it simply adds the packet to the Queue and then 1 SocketAsyncEventArgs simply loops to send that data.

但我怎么能做到这一点有效的同时仍然可扩展性?我想避免堵不如尽我所能,同时送我的包在他们被要求在被发送的顺序。

But how can I do this efficiently whilst still being scalable? I want to avoid blocking as much as I can whilst sending my packets in the order they are requested to be sent in.

鸭preciate任何帮助!

Appreciate any help!

推荐答案

如果数据需要保持秩序,而你不想阻止,那么你需要添加一个队列。我这样做的方式是通过跟踪,我的状态对象,我们是否已经有了一个激活的发送异步循环过程中该连接。排队(这显然必须是同步的)后,就检查什么是正在进行中的:

If the data needs to be kept in order, and you don't want to block, then you need to add a queue. The way I do this is by tracking, on my state object, whether we already have an active send async-loop in process for that connection. After enqueue (which obviously must be synchronized), just check what is in-progress:

    public void PromptToSend(NetContext context)
    {
        if(Interlocked.CompareExchange(ref writerCount, 1, 0) == 0)
        { // then **we** are the writer
            context.Handler.StartSending(this);
        }
    }

下面 writerCount 是写循环的次数(这应该是正好1或0)的连接;如果没有任何,我们开始的。

Here writerCount is the count of write-loops (which should be exactly 1 or 0) on the connection; if there aren't any, we start one.

我的 StartSending 试图从该连接的队列中读取;如果可以这样做,但它通常 SendAsync

My StartSending tries to read from that connection's queue; if it can do so, it does the usual SendAsync etc:

if (!connection.Socket.SendAsync(args)) SendCompleted(args);

(注意, SendCompleted 这里是同步的情况下,它会通过了以 SendCompleted 事件型号为异步的情况下)。 SendCompleted 重复这个出列,尝试发送异步的步骤,效果显着。

(note that SendCompleted here is for the "sync" case; it would have got to SendCompleted via the event-model for the "async" case). SendCompleted repeats this "dequeue, try send async" step, obviously.

剩下的唯一一件事就是确保我们的尝试的出列,我们注意到没有采取行动,如果我们觉得没有什么更多的事情要做:

The only thing left is to make sure that when we try to dequeue, we note the lack of action if we find nothing more to do:

        if (bufferedLength == 0)
        {  // nothing to do; report this worker as inactive
            Interlocked.Exchange(ref writerCount, 0);
            return 0;
        }

有意义吗?

这篇关于用的SocketAsyncEventArgs发送的订单数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆