【问题标题】:Async sockets in DD中的异步套接字
【发布时间】:2014-06-07 16:07:52
【问题描述】:

好的,这是我在 Stack Overflow 上的第一个问题,如果我没有正确提问,请直接回答。

基本上,我正在尝试使用 std.socket 编写一些异步套接字,但我不确定我是否正确理解了这个概念。我只在 C# 中使用过异步套接字,而在 D 中它似乎处于低得多的水平。我已经研究了很多并查找了很多代码、文档等以了解 D 和 C/C++,但是我不确定我是否正确理解了这个概念,以及你们是否有一些例子。我试着看一下 splat,但它已经过时了,而且 vibe 似乎对于一个简单的异步套接字包装器来说太复杂了。

如果我理解正确,std.socket 中没有 poll() 函数,那么您必须在 select() 上使用带有单个套接字的 SocketSet 来轮询套接字的状态,对吗?

所以基本上我将如何处理套接字是轮询以获取套接字的读取状态,如果它成功(值 > 0),那么我可以调用 receive(),它将返回 0 以表示断开连接,否则收到的值,但我必须继续这样做,直到收到预期的字节。

当然套接字设置为非阻塞!

对吗?

这是我目前编写的代码。

void HANDLE_READ()
{
    while (true)
    {
        synchronized
        {
            auto events = cast(AsyncObject[int])ASYNC_EVENTS_READ;
            foreach (asyncObject; events)
            {
                int poll = pollRecv(asyncObject.socket.m_socket);
                switch (poll)
                {
                    case 0:
                    {
                        throw new SocketException("The socket had a time out!");
                        continue;
                    }
                    default:
                    {
                        if (poll <= -1)
                        {
                            throw new SocketException("The socket was interrupted!");
                            continue;
                        }                    

                        int recvGetSize = (asyncObject.socket.m_readBuffer.length - asyncObject.socket.readSize);
                        ubyte[] recvBuffer = new ubyte[recvGetSize];
                        int recv = asyncObject.socket.m_socket.receive(recvBuffer);

                        if (recv == 0)
                        {
                            removeAsyncObject(asyncObject.event_id, true);
                            asyncObject.socket.disconnect();
                            continue;
                        }

                        asyncObject.socket.m_readBuffer ~= recvBuffer;                      
                        asyncObject.socket.readSize += recv;

                        if (asyncObject.socket.readSize == asyncObject.socket.expectedReadSize)
                        {
                            removeAsyncObject(asyncObject.event_id, true);
                            asyncObject.event(asyncObject.socket);
                        }
                        break;
                    }
                }
            }
        }
    }
}

【问题讨论】:

    标签: sockets asynchronous d


    【解决方案1】:

    所以基本上我将如何处理套接字是轮询以获取套接字的读取状态

    不太对。通常,想法是围绕select 构建一个事件循环,这样只要没有需要处理的网络或计时器事件,您的应用程序就会处于空闲状态。使用轮询时,您必须连续或在计时器上检查新事件,这会导致 CPU 周期的浪费,并且事件的处理时间会晚于它们发生的时间。

    在事件循环中,您使用您感兴趣的事件的套接字填充SocketSets。如果您想在套接字上收到新接收数据的通知,它将转到“可读”集。如果你有数据要发送,套接字应该在“可写”集中。并且所有套接字都应该在“错误”集上。

    select 然后将阻塞(睡眠)直到有事件出现,并用具有可操作事件的套接字填充SocketSets。然后,您的应用程序可以适当地响应它们:接收可读套接字的数据、发送可写套接字的排队数据以及执行错误套接字的清理。

    这是我的非光纤基于事件的网络的 D 实现:ae.net.asockets

    【讨论】:

    • 非常感谢!这正是我正在寻找的答案类型!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-04
    相关资源
    最近更新 更多