2

I'm trying to get a RIO server going for serving up requested data to a client, but every time I try to do a RIOSend, no data is transferred, and I get a 10022 completion status. I can receive requests and unpack them just fine, it just seems to be the send that's giving me problems.

I set up my socket as follows:

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 is then configured like this:

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!");
        }
    }
}

And after a receive is handled using RIODequeueCompletion, I check the data and send a response. The response code looks like so:

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!");
}

Anyone seeing anything glaringly obvious? This is the first time I've set up sockets from scratch, and my first time using RIO, so I'm sure I'm missing something here.

Thanks in advance.

MetalHeel
  • 21
  • 1

0 Answers0