【问题标题】:Sending data in order with SocketAsyncEventArgs使用 SocketAsyncEventArgs 按顺序发送数据
【发布时间】:2012-07-23 19:38:44
【问题描述】:

我最初在发送数据时遇到了竞争条件,问题是我允许使用多个 SocketAsyncEventArgs 来发送数据,但是第一个数据包在第二个数据包之前没有完全发送,这是因为我有它所以如果数据不适合缓冲区,它会循环直到所有数据都发送完毕,并且第一个数据包比第二个数据包大,第二个数据包很小,所以第二个数据包在第一个数据包之前被发送并到达客户端。

我已经解决了这个问题,将 1 个 SocketAyncEventArgs 分配给一个打开的连接以用于发送数据,并使用信号量来限制对它的访问,并在完成后让 SocketAsyncEventArgs 回调。

现在这工作正常,因为所有数据都已发送,并在完成下一次发送准备好时回调。这个问题是,当我想随机发送数据到打开的连接时,它会导致阻塞,当有大量数据发送时,它会阻塞我的线程。

我正在寻找解决此问题的方法,我想有一个队列,当请求发送数据时,它只是将数据包添加到队列中,然后 1 SocketAsyncEventArgs 简单地循环发送该数据。

但是我怎样才能在保持可扩展性的同时高效地做到这一点?在按照请求发送的顺序发送数据包时,我想尽可能避免阻塞。

感谢任何帮助!

【问题讨论】:

    标签: c# .net sockets packets socketasynceventargs


    【解决方案1】:

    如果数据需要保持有序,又不想阻塞,则需要添加队列。我这样做的方法是在我的状态对象上跟踪我们是否已经有一个用于该连接的活动发送异步循环。入队后(显然必须同步),只需检查正在进行的内容:

        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);如果没有,我们就开始一个。

    我的StartSending 尝试从该连接的队列中读取;如果可以的话,它会照常执行SendAsync 等:

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

    (注意这里的SendCompleted 用于“同步”情况;对于“异步”情况,它必须通过事件模型到达SendCompleted)。 SendCompleted 显然重复了这个“出队,尝试发送异步”步骤。

    剩下的唯一事情是确保当我们尝试出队时,如果我们发现没有更多可做的事情,我们会注意到缺乏行动:

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

    有意义吗?

    【讨论】:

    • 所以我会创建一个队列,当有东西添加到队列中时,检查发送操作是否已经在进行中,如果不是,则开始一个,它会一直循环直到队列是空的?一旦发送队列为空,将写入器计数更改为 0,并在需要时重新启动发送过程?
    • @mattysouthall 完全正确。请注意,“保持循环”有一个 async 循环,而不是常规循环 (while) 等。所以基本上,每当你收到“完成”事件时,你已经检查过它是好的等,然后开始下一个。
    • 一切都完成了,工作得很好!我的日志显示它的行为正是我想要的,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-28
    • 1970-01-01
    • 2012-02-26
    • 2012-06-13
    • 2015-05-09
    • 2013-06-07
    • 2021-02-05
    相关资源
    最近更新 更多