2

我试图让 RIO 服务器为客户端提供请求的数据,但每次我尝试执行 RIOSend 时,都没有数据传输,并且我得到 10022 完成状态。我可以很好地接收请求并将它们解包,这似乎是给我带来问题的发送。

我按如下方式设置我的套接字:

void socketSetup()
{
    WSADATA data;

    if (WSAStartup(0x202, &data) != 0)
        Logging::LogFatal("WSAStartup failed!");

    socket = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, WSA_FLAG_REGISTERED_IO);

    if (socket == INVALID_SOCKET)
        Logging::LogFatal("Socket creation error!");

    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = INADDR_ANY;

    if (bind(socket, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)) == SOCKET_ERROR)
        Logging::LogFatal("Socket bind error!");

    // Socket options.
    GUID functionTableId = WSAID_MULTIPLE_RIO;
    DWORD dwBytes = 0;

    int result = WSAIoctl(socket, SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER, &functionTableId, sizeof(GUID), (void**)&rio, sizeof(rio), &dwBytes, 0, 0);

    if (result != 0)
        Logging::LogFatal("Socket options error!");
}

然后像这样配置 RIO:

void rioSetup()
{
    // Create the queues.
    sendQueue = rio.RIOCreateCompletionQueue(bufferSize, 0);
    receiveQueue = rio.RIOCreateCompletionQueue(bufferSize, 0);

    if (sendQueue == RIO_INVALID_CQ || receiveQueue == RIO_INVALID_CQ)
        Logging::LogFatal("Error creating completion queues!");

    void *pContext = 0;

    requestQueue = rio.RIOCreateRequestQueue(socket, bufferSize / 2, 1, bufferSize / 2, 1, receiveQueue, sendQueue, pContext);

    if (requestQueue == RIO_INVALID_RQ)
        Logging::LogFatal("Error creating request queue!");

    // Allocate and register the buffers.
    sendBuffer = reinterpret_cast<char*>(VirtualAlloc(0, bufferSize * sizeof(DataProvider::TrackingData), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE));
    receiveBuffer = reinterpret_cast<char*>(VirtualAlloc(0, bufferSize * dataSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE));

    if (sendBuffer && receiveBuffer)
    {
        sendBufferId = rio.RIORegisterBuffer(sendBuffer, bufferSize * sizeof(DataProvider::TrackingData));
        receiveBufferId = rio.RIORegisterBuffer(receiveBuffer, bufferSize * dataSize);

        if (sendBufferId == RIO_INVALID_BUFFERID || receiveBufferId == RIO_INVALID_BUFFERID)
            Logging::LogFatal("Buffer register error!");

        // Slice up the receive buffer.
        DWORD offset = 0;

        RIO_BUF* receiveBufs = new RIO_BUF[bufferSize / 2];

        for (DWORD i = 0; i < bufferSize / 2; i++)
        {
            RIO_BUF* pBuf = receiveBufs + i;
            pBuf->BufferId = receiveBufferId;
            pBuf->Offset = offset;
            pBuf->Length = dataSize;

            offset += dataSize;

            if (!rio.RIOReceive(requestQueue, pBuf, 1, 0, pBuf))
                Logging::LogFatal("Error creating receives!");
        }
    }
}

在使用 RIODequeueCompletion 处理接收后,我检查数据并发送响应。响应代码如下所示:

void sendDataResponse(DataProvider::TrackingData data)
{
    memcpy(sendBuffer + currentSendOffset, &data, sizeof(DataProvider::TrackingData));

    RIO_BUF* pBuf = new RIO_BUF();
    pBuf->BufferId = sendBufferId;
    pBuf->Offset = currentSendOffset;
    pBuf->Length = sizeof(DataProvider::TrackingData);

    currentSendOffset += sizeof(DataProvider::TrackingData);

    if (currentSendOffset >= bufferSize * sizeof(DataProvider::TrackingData))
        currentSendOffset = 0;

    if (!rio.RIOSend(requestQueue, pBuf, 1, 0, pBuf))
        Logging::LogError("Error sending response!");
}

有人看到任何明显的东西吗?这是我第一次从头开始设置套接字,也是我第一次使用 RIO,所以我确定我在这里遗漏了一些东西。

提前致谢。

4

0 回答 0