所有代码如下  麻烦大神给看看 辛苦了
// Rs232Com.cpp: implementation of the CRs232Com class.
//
//////////////////////////////////////////////////////////////////////#include "stdafx.h"
#include "ComDataAgent.h"
#include "Rs232Com.h"#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////CRs232Com::CRs232Com()
: m_iTID(0)
{
hCom = 0;
hThread = 0;
IsOpen = false;
m_pParent = NULL;
}CRs232Com::~CRs232Com()
{}int CRs232Com::Open(CString strPortName)
{
   hCom = CreateFile( strPortName,
                    GENERIC_READ | GENERIC_WRITE,
                    0,    // must be opened with exclusive-access
                    NULL, // no security attributes
                    OPEN_EXISTING, // must use OPEN_EXISTING
                    FILE_FLAG_OVERLAPPED,    // not overlapped I/O
                    NULL  // hTemplate must be NULL for comm devices
                    );   if (hCom == INVALID_HANDLE_VALUE) 
   {
       // Handle the error.
       //TRACE ("CreateFile failed with error %d.\n", GetLastError());
       return 1;
   }   COMMTIMEOUTS cs;
   ::GetCommTimeouts(hCom,&cs);
   cs.ReadIntervalTimeout = 100;
   cs.ReadTotalTimeoutConstant = 100;
   cs.ReadTotalTimeoutMultiplier = 10;
   cs.WriteTotalTimeoutConstant = 100;
   cs.WriteTotalTimeoutMultiplier = 10;
   ::SetCommTimeouts(hCom,&cs);
   IsOpen = true;
   return 0;
}BOOL CRs232Com::GetCommState()
{
return ::GetCommState(hCom, &dcb);
}BOOL CRs232Com::SetCommState(DWORD Baud, DWORD ByteSize, DWORD Parity, DWORD StopBits)
{
  dcb.BaudRate = Baud;     // set the baud rate
dcb.ByteSize = (BYTE)ByteSize;             // data size, xmit, and rcv
dcb.Parity = (BYTE)Parity;        // no parity bit
dcb.StopBits = (BYTE)StopBits;    // one stop bit
dcb.EvtChar = 13;
   return ::SetCommState(hCom, &dcb);}
void CRs232Com::Close()
{
IsOpen = false;
if(hThread)
{
::WaitForSingleObject(hThread,1000*5);
CloseHandle(hThread);
}
if(hCom)
CloseHandle(hCom);
hCom = 0;
hThread = 0;
}#define MAX_RECV_BUFFER 8 * 1024
DWORD CRs232Com::ThreadProc(LPVOID lParam)
{
CRs232Com * pCom = (CRs232Com *)lParam;
CString strTID;
strTID.Format(_T("%d"),pCom->m_iTID); TRACE(strTID);
TRACE(_T("线程启动\n")); //20110825
int nBufferLen = 0;
char Buffer[MAX_RECV_BUFFER + 1]; memset(Buffer,0,MAX_RECV_BUFFER + 1); OVERLAPPED o;
o.hEvent = CreateEvent(
        NULL,   // default security attributes 
        TRUE,  // auto reset event 
        FALSE,  // not signaled 
        NULL    // no name
);
    o.Internal = 0;
    o.InternalHigh = 0;
    o.Offset = 0;
    o.OffsetHigh = 0;
// Clear comm buffers at startup
PurgeComm(pCom->hCom, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
DWORD dwr;
BOOL IsRead = false;
DWORD dwEvtMask = 0;
while(pCom->IsOpen)
{
ResetEvent(o.hEvent);
WaitCommEvent(pCom->hCom,&dwEvtMask,&o);

if(pCom->m_iTID == 100 && 0)
{
int ii = 0;
}
if (dwEvtMask & EV_RXCHAR) 
        {
           
DWORD dwError;
COMSTAT comstat; if(!pCom->IsOpen)
{
break;
}
BOOL bResult = ClearCommError(pCom->hCom, &dwError, &comstat); if (comstat.cbInQue == 0)
{
Sleep(10);
continue;
}
if(dwError != 0)
{
int i = 0;
}

OVERLAPPED o1;
o1.hEvent = CreateEvent(
NULL,   // default security attributes 
FALSE,  // auto reset event 
FALSE,  // not signaled 
NULL    // no name
);
o1.Internal = 0;
o1.InternalHigh = 0;
o1.Offset = 0;
o1.OffsetHigh = 0;
unsigned int nRemainLen = MAX_RECV_BUFFER - nBufferLen;
if(comstat.cbInQue > nRemainLen)
{
//comstat.cbInQue = 1024;
comstat.cbInQue = MAX_RECV_BUFFER - nBufferLen;
} //comstat.cbInQue = 100;
if(!pCom->IsOpen)
{
break;
}
//int ll = ReadFile(pCom->hCom,Buffer,comstat.cbInQue,&dwr,&o1);
int ll = ReadFile(pCom->hCom,Buffer + nBufferLen,comstat.cbInQue,&dwr,&o1);
//TRACE("20110825-----%d,%d\n",dwr,nBufferLen); int nFnd = nBufferLen;
nBufferLen += dwr;
for(;nFnd < nBufferLen;nFnd++)
{
if (Buffer[nFnd] == '\n' || Buffer[nFnd] == '\r')
{
char *tmpBuffer = new char[nFnd + 2];
if (tmpBuffer)
{
memcpy(tmpBuffer,Buffer,nFnd + 1);
memmove(Buffer,&Buffer[nFnd + 1],nFnd + 1);
nBufferLen -= (nFnd + 1); tmpBuffer[nFnd + 1] = '\0';

if((pCom->IsOpen) && (pCom->m_pParent))
pCom->m_pParent->SendMessage(WM_COMM_RXCHAR,(WPARAM)tmpBuffer,nFnd + 1);

nFnd = 0;
} //break;
}
}


        }

ResetEvent(o.hEvent);
o.Internal = 0;
o.InternalHigh = 0;
o.Offset = 0;
o.OffsetHigh = 0;
dwEvtMask = 0;
IsRead = false;
Sleep(10);
} TRACE(strTID);
TRACE(_T("线程结束\n"));
//theApp.m_pMainWnd->PostMessageW(WM_COMM_THREAD_END,0,0);
return 0;
}BOOL CRs232Com::SetCommMask(DWORD dwEvtMask)
{

::SetCommMask(hCom,dwEvtMask); hThread = CreateThread( 
            NULL,              // default security attributes
            0,                 // use default stack size  
            ThreadProc,        // thread function 
            this,             // argument to thread function 
            0,                 // use default creation flags 
            &dwThreadID);   // returns the thread identifier  return 0;
}int CRs232Com::Send(char * pBuff, long lLen)
{
if(IsOpen == false)
{
return -1;
} UCHAR sdata[1024];
memset(sdata,0,1024);
memcpy(sdata,pBuff,lLen);

DWORD num = 0;
OVERLAPPED o;
o.hEvent = CreateEvent(
        NULL,   // default security attributes 
        FALSE,  // auto reset event 
        FALSE,  // not signaled 
        NULL    // no name
);
    o.Internal = 0;
    o.InternalHigh = 0;
    o.Offset = 0;
    o.OffsetHigh = 0; //int re  = WriteFile(hCom,Buffer,Len,&num,&o);
int re  = WriteFile(hCom,sdata,lLen,&num,&o);
return num;
}

解决方案 »

  1.   

    I/O 异步的问题 好像三处在了OVELRLAPPE 这里
    但是具体我不知道怎么解决
      

  2.   

    既然使用了Overlapped,那么就需要遵循它的异步操作规则。WriteFile 之后接着通过WaitForSingleObject等待操作完成,然后通过GetOverlappedResult取得结果。下面是一段Delphi代码片段,仅仅参考:
           WriteFile(hFile, Buffer[0], Buffer_Ptr, m, @ovl);
          WaitForSingleObject(ovl.hEvent, INFINITE);
          GetOverlappedResult(hFile, ovl, m, true);
          SetFilePointer(hFile, m, nil, FILE_CURRENT);
      

  3.   

    这段代码写得比较简单,实际上应该在WriteFile之后,取GetLastError判断是否为ERROR_IO_PENDING(997),条件成立再WaitFor*,在实际应用当中WaitFor最好设置一个比较合理的超时时间,并判断结果是否为超时,如果不为超时才可以通过GetOverlappedResult取结果。相关的函数建议多参考一下MSDN当中的说明。