0

while I am writing some IOCP server-client codes, I saw misc behavior in IOCP.

The scenario goes here,

  1. Register Socket to IOCP
  2. Recv event catched by GetQueuedCompletionStatus
    while (!mExitFlag)
    {
        bool bSuccess = ::GetQueuedCompletionStatus(mIocpHandle, &dwIoSize, (PULONG_PTR)&client, (LPOVERLAPPED*)&ioData, INFINITE);
        
        logger->st = std::chrono::steady_clock::now();

        // ... queue to recv worker
    }
  1. then read buffer (char[]) related to iocp registered buffer (WSABUF)
        int dataLength = recvBytes; // when iocp completed
        int pktLength = Serializer::toInt32(mBuffer + mDataPos);
    
        if (dataLength > 0 && pktLength == 0)
        {
            using namespace std::chrono;

            char buffer[512];
            if (mBuffer[mDataPos] == 0)
            {
                // take snapshot
                memcpy(buffer, &mBuffer[mDataPos], dataLength);
            }

            while (mBuffer[mDataPos] == 0) { }
            
            // elapsed < 1ms 
            auto elapsed_in_microseconds = CTimer::count<microseconds>(mLogger->st);
            
            printf("elapsed %llu us", elapsed_in_microseconds);
            int val = mBuffer[mDataPos]; // this gives positive value

            throw std::runtime_error("serializer failed to read packet length");
        }

enter image description here

Snapshot in buffer[512] gives always 0 padded with dataLength.
After some microseconds elapsed, the mBuffer (WSABUF registered) is retrieved with data.
I checked the recv pending and handling in the single thread with log.

  • I observed this only happens when client sends huge data in shortly.
  • When the client sends data with term (10ms?), it was fine.

Does anyoneknows this IOCP issue?
Perhaps the solution can be waiting the buffer when client recv buffer is busy.

Y.frank
  • 56
  • 4
  • Did you check that the IOCP completion status is for the WSARecv call you made, not some other call? – user253751 Jun 27 '22 at 15:36
  • 1
    I figured out I was not using WSARecv correctly. I thought when WSARecv function argument LPDWORD lpNumberOfBytesRecvd gives greator than zero, can read without blocking. it was WSA_IO_PENDING, it needed to wait until iocp event. – Y.frank Jul 10 '22 at 04:19

0 Answers0