Browse Source

异步读写;

scbc.sat2 5 years ago
parent
commit
20b1bd85b8
2 changed files with 80 additions and 2 deletions
  1. 23 1
      短信猫/sms/sms/AsynSerial.cpp
  2. 57 1
      短信猫/sms/sms/AsynSerial.h

+ 23 - 1
短信猫/sms/sms/AsynSerial.cpp

@@ -3,10 +3,23 @@
 
 CAsynSerial::CAsynSerial(void):m_hComm(INVALID_HANDLE_VALUE)
 {
+	memset(&m_ovWait, 0, sizeof(OVERLAPPED));
+	memset(&m_ovRead, 0, sizeof(OVERLAPPED));
+	memset(&m_ovWrite, 0, sizeof(OVERLAPPED));
 }
 
 CAsynSerial::~CAsynSerial(void)
 {
+	Close();
+
+	if ( m_ovWait.hEvent )
+		CloseHandle(m_ovWait.hEvent);
+
+	if ( m_ovRead.hEvent )
+		CloseHandle(m_ovRead.hEvent);
+
+	if ( m_ovWrite.hEvent )
+		CloseHandle(m_ovWrite.hEvent);
 }
 
 BOOL CAsynSerial::Open(LPCTSTR pszPort, BOOL bOverlapped /* = FALSE*/) throw()
@@ -23,7 +36,16 @@ BOOL CAsynSerial::Open(LPCTSTR pszPort, BOOL bOverlapped /* = FALSE*/) throw()
 		bOverlapped ? FILE_FLAG_OVERLAPPED : 0,
 		NULL);
 
-	return (m_hComm != INVALID_HANDLE_VALUE);
+	if ( m_hComm != INVALID_HANDLE_VALUE )
+	{	
+		m_ovWait.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+		m_ovRead.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+		m_ovWrite.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+		return TRUE;
+	}
+
+	return FALSE;
 }
 
 BOOL CAsynSerial::Open(int nPort, DWORD dwBaud /* = 9600 */, int parity /* = NoParity */, BYTE DataBits /* = 8 */, int stopBits /* = OneStopBit */, int fc /* = NoFlowControl */, BOOL bOverlapped /* = FALSE */)

+ 57 - 1
短信猫/sms/sms/AsynSerial.h

@@ -51,7 +51,10 @@ public:
 		TwoStopBits
 	};
 protected:
-	HANDLE m_hComm;
+	HANDLE		m_hComm;
+	OVERLAPPED	m_ovWait;
+	OVERLAPPED	m_ovRead;
+	OVERLAPPED	m_ovWrite;	
 public:
 	CAsynSerial(void);
 	virtual ~CAsynSerial(void);
@@ -95,6 +98,38 @@ public:
 		return ReadFileEx(m_hComm, lpBuffer, dwNumberOfBytesToRead, lpOverlapped, lpCompletionRoutine);
 	}
 
+	// 必须先启用:SetMask(EV_ERR | EV_RXCHAR),才能使用WaitCommEvent;
+	BOOL ReadAsyn(void* lpBuffer, DWORD dwNumberOfBytesToRead, DWORD &dwNumberOfBytesRead) throw()
+	{
+		ATLASSERT(IsOpen());
+		COMSTAT cs = { 0 };
+		DWORD dwErrors = 0;
+		DWORD dwEvtMask = 0;
+		DWORD dwNumberOfBytesTransferred;
+
+		m_ovWait.Offset = 0;
+		m_ovRead.Offset = 0;
+		BOOL Status = WaitCommEvent(m_hComm, &dwEvtMask, &m_ovWait);
+		// WaitCommEvent也是一个异步命令,所以需要等待
+		if (!Status && GetLastError() == ERROR_IO_PENDING)
+		{
+			// 如果缓存中无数据线程会停在此,如果hCom关闭会立即返回False
+			Status = ::GetOverlappedResult(m_hComm, &m_ovWait, &dwNumberOfBytesTransferred, TRUE);
+		}
+		
+		ClearCommError(m_hComm, &dwErrors, &cs);
+		if (Status && dwEvtMask & EV_RXCHAR && cs.cbInQue > 0) //有数据
+		{		
+			dwNumberOfBytesTransferred = 0;			
+			memset(lpBuffer, 0, dwNumberOfBytesToRead);
+			// 数据已经到达缓存区,ReadFile不会当成异步命令,而是立即读取并返回True
+			Status = ReadFile(m_hComm, lpBuffer, dwNumberOfBytesToRead, &dwNumberOfBytesRead, &m_ovRead);
+			PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_RXABORT);
+		}
+
+		return Status;
+	}
+
 	BOOL Write(const void* lpBuffer, DWORD dwNumberOfBytesToWrite, DWORD& dwBytesWritten) throw()
 	{
 		ATLASSERT(IsOpen());
@@ -108,6 +143,27 @@ public:
 		return WriteFile(m_hComm, lpBuffer, dwNumberOfBytesToWrite, lpNumberOfBytesWritten, &overlapped);
 	}
 
+	// SetMask(EV_ERR | EV_RXCHAR);
+	BOOL WriteAsyn(const void* lpBuffer, DWORD dwNumberOfBytesToWrite, DWORD &dwNumberOfBytesWritten) throw()
+	{
+		ATLASSERT(IsOpen());
+		PurgeComm(m_hComm, PURGE_TXCLEAR|PURGE_TXABORT);
+
+		m_ovWait.Offset = 0;
+		BOOL bRet = WriteFile(m_hComm, lpBuffer, dwNumberOfBytesToWrite, &dwNumberOfBytesWritten, &m_ovWrite);
+
+		if (!bRet && GetLastError() == ERROR_IO_PENDING)//后台读取
+		{
+			//等待数据写入完成
+			if (FALSE == ::GetOverlappedResult(m_hComm, &m_ovWrite, &dwNumberOfBytesWritten, TRUE))
+			{
+				return FALSE;
+			}
+		}
+
+		return bRet;
+	}
+
 	BOOL WriteEx(LPCVOID lpBuffer, DWORD dwNumberOfBytesToWrite, LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) throw()
 	{
 		ATLASSERT(IsOpen());