⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serial.cpp

📁 VC网络程序设计实例导航配套代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSerial::SetRTS
// 功能描述     : 
// 参数         : BOOL OnOrOff
// 返回值       : BOOL 
//
///////////////////////////////////////////////////////////////////////
BOOL CSerial::SetRTS(BOOL OnOrOff)
{
	return IsOpen() ? ::EscapeCommFunction(m_hCom, OnOrOff ? SETRTS:CLRRTS):FALSE;
}


///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSerial::SetBreak
// 功能描述     : 
// 参数         : BOOL OnOrOff
// 返回值       : BOOL 
//
///////////////////////////////////////////////////////////////////////
BOOL CSerial::SetBreak(BOOL OnOrOff)
{
	return IsOpen() ? ::EscapeCommFunction(m_hCom, OnOrOff ? SETBREAK:CLRBREAK):FALSE;
}


///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSerial::SetMaskEvent
// 功能描述     : 
// 参数         : DWORD dwMask
// 返回值       : void 
//
///////////////////////////////////////////////////////////////////////
void CSerial::SetMaskEvent(DWORD dwMask)
{
	m_dwMaskEvent = dwMask;
}


///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSerial::OnCTS
// 功能描述     : 
// 返回值       : void 
//
///////////////////////////////////////////////////////////////////////
void CSerial::OnCTS()
{
	if(::IsWindow(m_hNotifyWnd))
	{
		DWORD dwStatus;
		if(GetCommModemStatus(m_hCom, &dwStatus))
			::SendMessage(m_hNotifyWnd, WM_COM_CTS, 0, dwStatus&MS_CTS_ON ? 1:0);
	}
}


///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSerial::OnDSR
// 功能描述     : 
// 返回值       : void 
//
///////////////////////////////////////////////////////////////////////
void CSerial::OnDSR()
{
	if(::IsWindow(m_hNotifyWnd))
	{
		DWORD dwStatus;
		if(::GetCommModemStatus(m_hCom, &dwStatus))
		{
			::SendMessage(m_hNotifyWnd, WM_COM_DSR, 0, dwStatus&MS_DSR_ON ? 1:0);
		}
	}
}


///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSerial::OnRing
// 功能描述     : 
// 返回值       : void 
//
///////////////////////////////////////////////////////////////////////
void CSerial::OnRing()
{
	if(::IsWindow(m_hNotifyWnd))
		::SendMessage(m_hNotifyWnd, WM_COM_RING, 0, 0);
}


///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSerial::OnRLSD
// 功能描述     : 
// 返回值       : void 
//
///////////////////////////////////////////////////////////////////////
void CSerial::OnRLSD()
{
	if(::IsWindow(m_hNotifyWnd))
		::SendMessage(m_hNotifyWnd, WM_COM_RLSD, 0, 0);
}


///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSerial::OnBreak
// 功能描述     : 
// 返回值       : void 
//
///////////////////////////////////////////////////////////////////////
void CSerial::OnBreak()
{
	if(::IsWindow(m_hNotifyWnd))
		::SendMessage(m_hNotifyWnd, WM_COM_BREAK, 0, 0);
}


///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSerial::OnError
// 功能描述     : 
// 返回值       : void 
//
///////////////////////////////////////////////////////////////////////
void CSerial::OnError()
{
	DWORD dwError;
	::ClearCommError(m_hCom, &dwError, NULL);
	if(::IsWindow(m_hNotifyWnd))
		::SendMessage(m_hNotifyWnd, WM_COM_ERROR, 0, dwError);
}


///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSerial::OnReceive
// 功能描述     : 
// 返回值       : void 
//
///////////////////////////////////////////////////////////////////////
void CSerial::OnReceive()
{
	if(::IsWindow(m_hNotifyWnd))
		::SendMessage(m_hNotifyWnd, WM_COM_RECEIVE, 0, 0);
}


///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSerial::OnTXEmpty
// 功能描述     : 
// 返回值       : void 
//
///////////////////////////////////////////////////////////////////////
void CSerial::OnTXEmpty()
{
	if(::IsWindow(m_hNotifyWnd))
		::SendMessage(m_hNotifyWnd, WM_COM_TXEMPTY, 0, 0);
}


// ---------------------------CSCSerial类---------------------------------//


///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSCSerial::CSCSerial
// 功能描述     : 
// 参数         : CSerial *pSerial
// 返回值       : 
//
///////////////////////////////////////////////////////////////////////
CSCSerial::CSCSerial(CSerial *pSerial)
{
	pSerial->SetNotifyNum(sizeof(CSerialFrame));
	pSerial->SetMaskEvent(EV_RXCHAR | EV_BREAK | EV_TXEMPTY);
	m_pSerial = pSerial;
	m_sequence = 0;
	m_nStatus = STATUS_IDLE;
}


///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSCSerial::ReadFrame
// 功能描述     : 
// 返回值       : CSerialFrame* 
//
///////////////////////////////////////////////////////////////////////
CSerialFrame* CSCSerial::ReadFrame()
{
	CSerialFrame *pFrame = (CSerialFrame *)m_DataBuff;
	if(m_pSerial->ReadData(m_DataBuff, sizeof(CSerialFrame), 100))
		return pFrame;
	else
		return NULL;
}


///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSCSerial::ReadData
// 功能描述     : 
// 返回值       : CSerialFrame* 
//
///////////////////////////////////////////////////////////////////////
CSerialFrame* CSCSerial::ReadData()
{
	CSerialFrame *pFrame = (CSerialFrame *)m_DataBuff;
	int nChecksum;
	// 试图读取帧头
	if(m_pSerial->ReadData(m_DataBuff, sizeof(CSerialFrame), 100))
	{
		// 检查贞大小
		if(pFrame->uDataLen > FRAME_SIZE)
		{
			m_pSerial->Purge();
			return NULL;
		}

		// 传输其他字节
		if(pFrame->uDataLen > 0)
		{
			if(!m_pSerial->ReadData(pFrame + 1, pFrame->uDataLen, 600))
			{
				m_pSerial->Purge();
				TRACE(" CSerialServer::ReadData  读取数据超时 \r\n");
				return NULL;
			}
		}

		// 检查效验位
		nChecksum = pFrame->uChecksum;
		pFrame->uChecksum = 0;
		if(nChecksum != checksum((USHORT*)pFrame, sizeof(CSerialFrame) + pFrame->uDataLen))
		{
			TRACE(" CSerialServer::ReadData  数据效验出错 \r\n");
			SendRetry();
			return NULL;
		}

		return pFrame;
	}
	else
	{
		m_pSerial->Purge();
		return NULL;
	}
}


///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSCSerial::SendCommand
// 功能描述     : 
// 参数         : BYTE command
// 返回值       : BOOL 
//
///////////////////////////////////////////////////////////////////////
BOOL CSCSerial::SendCommand(BYTE command)
{
	CSerialFrame frame;

	memset(&frame, 0, sizeof(frame));

	frame.command = command;
	frame.uDataLen = 0;

	frame.uChecksum = checksum((USHORT*)&frame, sizeof(frame));

	if(m_pSerial->Write(&frame, sizeof(frame)) != sizeof(frame))
			return FALSE;
	return TRUE;
}


///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSCSerial::SendRetry
// 功能描述     : 
// 返回值       : BOOL 
//
///////////////////////////////////////////////////////////////////////
BOOL CSCSerial::SendRetry()
{
	CSerialFrame frame;

	memset(&frame, 0, sizeof(frame));

	frame.command = SERIAL_ERROR;
	frame.uDataLen = 0;

	frame.uChecksum = checksum((USHORT*)&frame, sizeof(frame));

	if(m_pSerial->Write(&frame, sizeof(frame)) != sizeof(frame))
			return FALSE;

	return TRUE;
}


///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSCSerial::SendAck
// 功能描述     : 
// 返回值       : BOOL 
//
///////////////////////////////////////////////////////////////////////
BOOL CSCSerial::SendAck()
{
	CSerialFrame frame;

	memset(&frame, 0, sizeof(frame));

	frame.command = SERIAL_ACK;
	frame.uDataLen = 0;

	frame.uChecksum = checksum((USHORT*)&frame, sizeof(frame));

	if(m_pSerial->Write(&frame, sizeof(frame)) != sizeof(frame))
			return FALSE;

	return TRUE;
}


///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSCSerial::SendData
// 功能描述     : 
// 参数         : LPVOID Buffer
// 参数         : int nBufferLen
// 返回值       : BOOL  
//
///////////////////////////////////////////////////////////////////////
BOOL  CSCSerial::SendData(LPVOID Buffer, int nBufferLen)
{
	if(nBufferLen > FRAME_SIZE)
		return FALSE;

	CSerialFrame *pFrame = (CSerialFrame *)m_DataBuff;
	memset(pFrame, 0, sizeof(CSerialFrame));

	// 构建贞
	pFrame->command = SERIAL_DATA;
	pFrame->uDataLen = nBufferLen;
	pFrame->sequence = m_sequence;
	memcpy(pFrame + 1, Buffer, nBufferLen);

	pFrame->uChecksum = checksum((USHORT*)pFrame, sizeof(CSerialFrame) + nBufferLen);

	if(m_pSerial->Write(pFrame, sizeof(CSerialFrame) + nBufferLen) 
			!= sizeof(CSerialFrame) + nBufferLen)
		return FALSE;
	return TRUE;
}



///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSCSerial::SendFileSize
// 功能描述     : 
// 参数         : DWORD dwSize
// 返回值       : BOOL 
//
///////////////////////////////////////////////////////////////////////
BOOL CSCSerial::SendFileSize(DWORD dwSize)
{

	char buff[sizeof(CSerialFrame) + sizeof(DWORD)];
	memset(buff, 0, sizeof(CSerialFrame) + sizeof(DWORD));


	CSerialFrame *pFrame = (CSerialFrame *)buff;
	CSerialFrame recv;

	// build frame
	pFrame->command = SERIAL_SIZE;
	pFrame->uDataLen = sizeof(DWORD);
	*(DWORD*)(pFrame + 1) = dwSize;

	pFrame->uChecksum = checksum((USHORT*)pFrame, sizeof(CSerialFrame) + sizeof(DWORD));
	
	
	// send it
	if(m_pSerial->Write(pFrame, sizeof(CSerialFrame) + sizeof(DWORD)) 
						!= sizeof(CSerialFrame) + sizeof(DWORD))
		return FALSE;
	
	// wait for ack
	if(m_pSerial->ReadData(&recv, sizeof(recv), 1500))
	{
		// 检查效验和
		int nChecksum = recv.uChecksum;
		recv.uChecksum = 0;
		if(nChecksum != checksum((USHORT*)&recv, sizeof(recv)))
			return FALSE;
		
		if(recv.command == SERIAL_ACK)
			return TRUE;
		else
			return FALSE;
	}
	return FALSE;
}


///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSCSerial::SendFileData
// 功能描述     : 
// 参数         : LPVOID Buffer
// 参数         : int nBufferLen
// 返回值       : BOOL 
//
///////////////////////////////////////////////////////////////////////
BOOL CSCSerial::SendFileData(LPVOID Buffer, int nBufferLen)
{
	if(nBufferLen > FRAME_SIZE)
		return FALSE;

	CSerialFrame *pFrame = (CSerialFrame *)m_DataBuff;
	memset(pFrame, 0, sizeof(CSerialFrame));

	// 构建贞
	pFrame->command = SERIAL_DATA;
	pFrame->uDataLen = nBufferLen;
	pFrame->sequence = m_sequence;
	memcpy(pFrame + 1, Buffer, nBufferLen);

	pFrame->uChecksum = checksum((USHORT*)pFrame, sizeof(CSerialFrame) + nBufferLen);



	while(TRUE)
	{
		CSerialFrame ack;
		if(m_pSerial->Write(pFrame, sizeof(CSerialFrame) + nBufferLen) 
			!= sizeof(CSerialFrame) + nBufferLen)
			return FALSE;
		
		if(m_pSerial->ReadData(&ack, sizeof(ack), 1500))
		{
			// 检查效验和
			int nChecksum = ack.uChecksum;
			ack.uChecksum = 0;
			if(nChecksum != checksum((USHORT*)&ack, sizeof(ack)))
				return FALSE;

			if(ack.command == SERIAL_ACK)
			{
				m_sequence++;
				return TRUE;
			}
			else if(ack.command == SERIAL_ERROR)
				continue;
			else
				return FALSE;
		}
		else
			return FALSE;
	}
	return FALSE;
}


///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSCSerial::SendEOF
// 功能描述     : 
// 返回值       : BOOL 
//
///////////////////////////////////////////////////////////////////////
BOOL CSCSerial::SendEOF()
{
	// 构建数据帧
	CSerialFrame frame, ack;
	memset(&frame, 0, sizeof(frame));

	frame.command = SERIAL_EOF;
	frame.uDataLen = 0;

	// 计算校验和
	frame.uChecksum = checksum((USHORT*)&frame, sizeof(frame));
	
	// 发送数据帧
	if(m_pSerial->Write(&frame, sizeof(frame)) != sizeof(frame))
		return FALSE;
	
	// 接收对方的“确认”消息
	if(m_pSerial->ReadData(&ack, sizeof(ack), 1500))
	{
		// 检查效验和
		int nChecksum = ack.uChecksum;
		ack.uChecksum = 0;
		if(nChecksum != checksum((USHORT*)&ack, sizeof(ack)))
			return FALSE;
		
		if(ack.command == SERIAL_ACK)
		{
			return TRUE;
		}
		else
			return FALSE;
	}
	
	return FALSE;
}


///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSCSerial::SendAbort
// 功能描述     : 
// 返回值       : BOOL 
//
///////////////////////////////////////////////////////////////////////
BOOL CSCSerial::SendAbort()
{
	CSerialFrame frame, ack;
	memset(&frame, 0, sizeof(frame));

	frame.command = SERIAL_ABORT;
	frame.uDataLen = 0;
	frame.uChecksum = checksum((USHORT*)&frame, sizeof(frame));
	
	
	if(m_pSerial->Write(&frame, sizeof(frame)) != sizeof(frame))
		return FALSE;
	
	if(m_pSerial->ReadData(&ack, sizeof(ack), 1500))
	{
		// 检查效验和
		int nChecksum = ack.uChecksum;
		ack.uChecksum = 0;
		if(nChecksum != checksum((USHORT*)&ack, sizeof(ack)))
			return FALSE;
		
		if(ack.command == SERIAL_ACK)
		{
			return TRUE;
		}
		else
			return FALSE;
	}
	return FALSE;
}


///////////////////////////////////////////////////////////////////////
//
// 函数名       : CSCSerial::SendInit
// 功能描述     : 
// 返回值       : BOOL 
//
///////////////////////////////////////////////////////////////////////
BOOL CSCSerial::SendInit()
{ 
	return SendCommand(SERIAL_INIT); m_nStatus = STATUS_IDLE; 
}




///////////////////////////////////////////////////////////////////////
//
// 函数名       : checksum
// 功能描述     : 计算校验和
// 参数         : USHORT* buff		要计算校验和的缓冲区
// 参数         : int size			buff缓冲区的大小
// 返回值       : USHORT			数据的校验和	
//
///////////////////////////////////////////////////////////////////////
USHORT checksum(USHORT* buff, int size) 
{
	unsigned long cksum = 0;
	while(size>1)
	{
		cksum += *buff++;
		size -= sizeof(USHORT);
	}
	// 是奇数
	if(size)
	{
		cksum += *(UCHAR*)buff;
	}
	// 将32位的chsum高16位和低16位相加,然后取反
	cksum = (cksum >> 16) + (cksum & 0xffff);
	cksum += (cksum >> 16);			
	return (USHORT)(~cksum);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -