GetQueuedCompletionStatus返回错误信息

时间:2014-11-14 20:35:32

标签: c++ windows iocp

我正在使用IOCP编写多播生产者和多播消费者应用程序。我的制作人应用程序是多线程的,并发布到多个多播渠道。每个通道都在自己的线程上发布,所以我确定发送缓冲区没有同步/竞争条件问题。事实上,使用wire shark,数据报看起来很好(偶尔会出现一个格式错误(不确定UDP数据报是否正常)。)

我的消费者应用程序是我遇到麻烦的地方。我的消费者应用程序也是多线程的。但同样,对于任何单个多播通道只调用一个WSARecv(每个通道都有自己的一组缓冲区),因此只有一个线程访问缓冲区。当我调用GetQueuedCompletionStatus时,我处理数据,然后调用WSARecv再次启动进程。

我看到的问题是GetQueuedCompletionStatus返回缓冲区中的旧数据(我重用了缓冲区)。当我将缓冲区写入日志文件时,我可以看到数据没有变化,尽管我的Wire Shark记录显示数据报很好。这个错误的间歇性似乎指向同步问题,但我仔细查看了库,我没有看到使用TCP的这个问题。 GetQueuedCompletionStatus有没有办法返回虚假数据?

bool cont = true;
DWORD xferd;
OVERLAPPED* overlapped = NULL;
TTOverlapped<InternalEndpointPtr>* tto;
ULONG_PTR key;

while (cont) {
    BOOL b = GetQueuedCompletionStatus(iocp_, &xferd, &key, &overlapped, INFINITE);

    // only a single WSARecv called per overlapped structure
    // it's assumed that if overlapped != NULL, WSARecv call has completed
    if (overlapped) {
        tto = static_cast<TTOverlapped<InternalEndpointPtr>*>(overlapped);

        switch (tto->opCode()) {
        case IOCP_OP_CODE_READ: readMessage(tto, xferd); break;
        case IOCP_OP_CODE_WRITE:
            if (xferd == 0)
                std::printf("Send operation failed: %d.\n", WSAGetLastError());
            break;
        case IOCP_OP_CODE_NEW_CLIENT:
            tto->endpoint()->recv();
            delete tto;
            break;
        case IOCP_OP_CODE_SHUTDOWN:
            cont = false;
            break;
        default
            std::printf("Not expecting this: %d!!!\n", tto->opCode());
            break;
        }
    }
    else {
        DWORD d = GetLastError();
        if (d != 995)
            Logger::log(LOG_LEVEL_STATUS, LOG_TYPE_SYSTEM, "InternalIpcProcessor::processIocpCallbacks(): GetQueuedCompletionStatus returned FALSE. Thread id = %d. GetLastError = %d.", ::GetCurrentThreadId(), GetLastError());
    }
}

0 个答案:

没有答案
相关问题