2012-11-28 93 views
1

我有一个线程,不断寻找新的数据,如果数据不是已经在串行缓冲器,ReadFileGetOverlappedResult似乎在告诉我有数据,而且它读出来,但是不是转移到我的缓冲区...使用GetOverlappedResult丢失数据?

func read() 
{ 
    if(state == 0) 
    { 
     memset(bytes, '\0', sizeof(amount_to_read)); 

     readreturn = ReadFile(h, bytes, amount_to_read,NULL, osReader); 
     if(readreturn <= 0) 
     { 
      errorcode = GetLastError(); 
      if(errorcode != ERROR_IO_PENDING) 
      { 
       SetEAIError(ERROR_INTERNALERROR); 
       return -1; 
      } 
     } 
    } 

    if (GetOverlappedResult(h, osReader, &dwRead, FALSE) == false) 
    { 
     errorcode = GetLastError(); 

     if (errorcode == ERROR_IO_INCOMPLETE || errorcode == 0) 
     { 
      if(dwRead > 0) 
      { 
       return 1; 
      } 
      //timeout 
      SetEAIError(ERROR_EAITIMEOUT); 
      return -1; 
     } 
     else 
     { 
      //other error 
      SetEAIError(ERROR_WIN_ERROR); 
      return -1; 
     } 
    } 
    else 
    { 
     //read succeded, check if we read the amount required 
     if(dwRead != amount_to_read) 
     { 
      if(dwRead == 0) 
      { 
       //nothing read, treat as timeout 
       SetEAIError(ERROR_EAINOREAD); 
       return -1; 
      } 
      else 
      { 
       //memcpy_s(bytes, sizeof(bytes), readbuf, dwRead); 
       SetEAIError(ERROR_PARTIALREAD); 
       *_bytesRead = dwRead; 
       return -1; 
      } 
     } 
     else 
     { 
      if(strlen((char*)bytes) == 0) 
      { 
       //nothing read, treat as timeout 
       SetEAIError(ERROR_EAINOREAD); 
       return -1; 
      } 
      //memcpy_s(bytes, sizeof(bytes), readbuf, dwRead); 
      *_bytesRead = dwRead; 
      return 0; 
     } 
    } 
} 

这是个什么错误代码的意思是:

  • ERROR_TIMEOUT - 切换状态为1,这样就不会再次读取,这就要求GetOverlappedResult再次

  • InternalError该,ERROR_EAINOREAD - 它复位状态,以0

  • ERROR_PARTIALREAD - 始于字节的新大小的新的读取读取

如果我于swtich GetOverlappedResult阻塞(通过TRUE)它屡试不爽。 如果将我的线程,只有当我知道读有数据有它屡试不爽。

但是,如果那里没有数据,当有数据时它似乎“丢失”了数据,它我读取的数量参数dwRead显示正确的读取字节数(可以看到它用端口监视器读取),但字节不存储在我的char *中。

我不断得到ERROR_EAINOREAD

我在做什么错?

我不想使用标志,我想只是使用ReadFileGetOverlappedResult,我应该能够与我的代码来完成这个.......我认为

+1

你'memset的(字节,“\ 0” ,的sizeof(amount_to_read));'是错误的,除非你只想清除缓冲区,其中'N'值是sizeof任何变量**类型的第一个'N'字节**的'amount_to_read'是。这可能是为什么你认为有数据在那里,但实际上并没有 – WhozCraig

+0

约定,不应该是字节的大小... 我认为这里有数据的原因虽然是因为getoverlappedresults将dwRead DWORD设置为6个,但我的数组是全零 (也指出,我知道我使用的strlen来测试这一点,我的数据对第一个空字符没有零点所以这是一个快速的黑客,strlen的回报,通常不会工作,但那不是我的问题,无论我在监视窗口已经验证) – morty346

+1

OK,最后一个问题,在那里'state'在这种情况下更新?我问,因为你显然需要启动阅读,但'状态'不在此代码中,除了eval。我可以假设它在这之外?不管你是否打算这样做,这*看起来就像你本质上试图发出一个重叠的异步读请求,然后在GetOverlappedResult上旋转循环,试图从它读取数据。我通常使用可更改的IO,或者更好的是,IOCP为此,但必须有一个原因,你不这样做。 – WhozCraig

回答

3

问题正是数据丢失的原因是什么?丢失的原因是因为传入readfile的bytes参数是父线程中的局部变量。是本地它得到重新所以以后我接触到的阅读再次初始化每个周期,跳过ReadFile和转到overlappedresults,我现在可能与内存的不同区域工作

+1

这肯定会导致问题。每个IO操作都需要(a)它自己的OVERLAPPED严格的,和(b)只要请求'在那里',存储器就在其周围,我很高兴你有* *出于该doc = P – WhozCraig