sockets - D 中的异步套接字

标签 sockets asynchronous d

好的,这是我在 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;
                    }
                }
            }
        }
    }
}

最佳答案

So basically how I'd go about handling the sockets is polling to get the read status of the socket



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

在事件循环中,您填充 SocketSet s 与您感兴趣的事件的套接字。如果您想在套接字上收到新接收数据的通知,它会转到“可读”集。如果您有数据要发送,则套接字应位于“可写”集中。并且所有套接字都应该在“错误”集上。
select然后将阻塞(休眠)直到事件进入,并填充 SocketSet s 与具有可操作事件的套接字。然后,您的应用程序可以适本地响应它们:接收可读套接字的数据,发送可写套接字的排队数据,并对错误的套接字执行清理。

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

关于sockets - D 中的异步套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24099090/

相关文章:

Javascript:在 x 次异步数据库/ajax 调用后是否有更好的方法来执行函数

ios - 从 Swift 函数中的异步调用返回数据

d - 拆分/拆分的编译问题

exception - 如何停止 Vibe.D 应用程序?

c++ - 什么相当于 C++ 中 D 的 taskPool.parallel()

c# - 从firefox扩展名连接到C#应用程序中的localhost服务器

Java构造http请求报文

java - 为什么套接字不使用 ip 而不是 localhost 连接?

Python 套接字聊天客户端 - select.select() 和 sys.stdin 的问题

node.js - ForEach 循环中的异步/等待 Node -Postgres 查询