2012-07-27 63 views
0

嗯,我做一個IOCP用於處理與以下詳細信息的客戶端連接:IOCP和覆蓋緩衝

- Threads = (CPU cores * 2) 
- Assigning an completion port to each socket 
- Accessing the socket context by Client Index or overlapped struct (either way is the same) 

,所以我嘗試調試傳入的數據包,就像一個魅力的作品,除了一點點,但討厭細節...我在WorkersThread函數(我recv數據包)上設置了一箇中斷點,我正在用包recv監視數據包的緩衝區,突然緩衝區被我從客戶端獲得的新數據包覆蓋。

這是爲什麼?根據我讀的內容,IOCP應該等到我處理數據包,在收到其他數據包之前向客戶端發送響應。所以我在我的名爲「Processing」的套接字上下文中設置了一個標誌,並且仍然使用傳入的數據包覆蓋了緩衝區。所以它不讓我調試,它讓我瘋狂

是ollydbg(調試器)故障,讓其他線程運行時,我設置了一個斷點?或者是我的IOCP實施中出現一些錯誤?

這裏是我的WorkerThread是如何編碼:在clientinfo-> RecvContext.Buffer看時出現

DWORD WINAPI WorkerThread(void* argument) 
{ 
    int BytesTransfer; 
    int BytesRecv; 
    int ClientID; 
    int result; 
    OVERLAPPED* overlapped = 0; 
    ClientInfo* clientinfo = 0; 
    WSABUF wsabuf; 
    int flags; 
    //Exit only when shutdown signal is recv 
    while (WaitForSingleObject(IOCPBase::internaldata->sockcontext.ShutDownSignal, NULL) != WAIT_OBJECT_0) 
    { 
     flags = 0; BytesTransfer = 0; BytesRecv = 0; ClientID = 0; 
     //Get from queued list 
     if (GetQueuedCompletionStatus(IOCPBase::internaldata->sockcontext.CompletionPort, (LPDWORD)&BytesTransfer, (PULONG_PTR)&ClientID, &overlapped, INFINITE) == TRUE) 
     { 
      if (overlapped == 0) 
      { 
       //Fatal error 
       break; 
      } 
      clientinfo = (ClientInfo*)overlapped; 
      if (BytesTransfer != 0) 
      { 
       //Assign the buffer pointer and buffer len to WSABUF local 
       clientinfo->RecvContext.RecvBytes = BytesTransfer; 
       wsabuf.buf = (char*)clientinfo->RecvContext.Buffer; 
       wsabuf.len = clientinfo->RecvContext.Len; 
       //Switch for OperationCode 
       //switch (IOCPBase::internaldata->ClientContext[ClientID].OperationCode) 
       switch (clientinfo->OperationCode) 
       { 
       case FD_READ: 
        // Check if we have send all data to the client from a previous send 
        if (clientinfo->SendContext.SendBytes < clientinfo->SendContext.TotalBytes) 
        { 
         clientinfo->OperationCode = FD_READ;    //We set FD_READ caused on the next send, there could still be bytes left to send 
         wsabuf.buf += clientinfo->SendContext.SendBytes; //The buffer position is + sended bytes 
         wsabuf.len = clientinfo->SendContext.TotalBytes - clientinfo->SendContext.SendBytes; //the buffer len is total - sended bytes 
         //Send the remain bytes 
         result = WSASend(clientinfo->sock, &wsabuf, 1, (LPDWORD)&BytesRecv, flags, &clientinfo->overlapped, NULL); 
         if (result == SOCKET_ERROR && (WSAGetLastError() != WSA_IO_PENDING)) 
         { 
          CloseClient(ClientID); 
         } 
         clientinfo->SendContext.SendBytes += BytesRecv; 
        } 
        else 
        { 
         if (clientinfo->Processing == 0) 
         { 
          clientinfo->OperationCode = FD_WRITE; //If no more bytes left to send now we can set the operation code to write (in fact is read) 
          memset(clientinfo->RecvContext.Buffer, NULL, MAX_DATA_BUFFER_SIZE); //Clean the buffer for recv new data 
          //Recv data from our client 
          clientinfo->RecvContext.RecvBytes = WSARecv(clientinfo->sock, &wsabuf, 1, (LPDWORD)&BytesRecv, (LPDWORD)&flags, &clientinfo->overlapped, NULL); 
          if (clientinfo->RecvContext.RecvBytes == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING) 
          { 
           CloseClient(ClientID); 
           break; 
          } 
         } 
        } 
        break; 
       case FD_WRITE: 
        //Send data to the RecvProtocol 
        clientinfo->Processing = 1; 
        IOCPBase::internaldata->callback.RecvProtocol(clientinfo->RecvContext.Buffer, clientinfo->RecvContext.Len, ClientID); 
        clientinfo->Processing = 0; 
       default: 
        break; 
       } 
      } 
     } 
    } 
    return false; 
} 

的問題。我正在看數據包,過了幾秒鐘,並且用新數據包覆蓋緩衝區。

謝謝!

+0

只需要注意,在'FD_READ'的情況下,你在'if'語句中有一個'break'語句,這個'break'將不會中斷循環,因爲它在'switch'中。您必須重新設計算法,或使用例如'goto'。 – 2012-07-27 07:15:29

回答

0

沒關係我通過將數據包複製到我用來分析數據包的函數的堆棧幀來修復調試問題,這樣我就沒有覆蓋問題了。