无线传感网络课程论文
::ReadFile(m_hFile,pData,iLen,pdwRead,lpOverlapped);//读串口 ::WriteFile(m_hFile,pData,iLen,pdwWritten,lpOverlapped);//写串口
4.4 客户端
相对于服务器,客户端的设计和实现比较简单。客户端只需要建立同服务器的Socket连接,发送数据,接受服务器发送来的数据即可。其流程如图:
初始化建立连接接收和发送数据断开连接 图 10 客户端处理流程
相关代码:
[...] 初始化
m_ClientSocket.Create(); //创建套接字
m_ClientSocket.Connect(buf,m_ServerPort);//建立连接 m_ClientSocket.Send(m_Send,m_Send.GetLength());//发送数据 //接收数据
m_ClientSocket.Receive(GetBuffer(1024),m_Receive.GetLength(); m_ClientSocket.Close(); //断开连接
21
无线传感网络课程论文
4.5 类图
CNTService-m_bIsRunning : bool = false-m_hEventSource-m_iMajorVersion-m_iMinorVersion-m_pThis-m_szServiceName-m_AcceptSocket+Handler()+Inialize()+Install()+IsInstalled()+OnContinue()+OnInit()+OnInterrogate()+OnPause()+OnShutdown()+OnStop()+ParseStandardArgs()+Run()+ServiceMain()+StratService()+Uninstall()+AnswerThread()CSerial-m_dwEventMask-m_eEvent-m_fStopping : bool = true-m_hevtOverlapped-m_hFile-m_hThread-m_lLastError-m_Socket+CheckPort()+Close()+GetEventMask()+GetEventType()+Open()+Read()+SetMask()+Setup()+StartListener()+ThreadProc()+WaitEvent()+Write()SafeQueue-first-last-lock+IsEmpty()+Pop()+Push()+Reset()
图 11 类图
CNTService:Windows NT服务类,实现了Windows NT的服务。 CSerial:串口类,实现串口通信。
SafeQueue:安全队列类,实现多线程安全访问队列。
4.6 附件
#if defined (ZTOOL_P1) || defined (ZTOOL_P2) uartConfig.callBackFunc = rxCB; ? 声明一个事件(SampleApp.h)
#define UART_RX_CB_EVT 0x0002 ? uart回调函数(MT_UART.c):
static void rxCB( uint8 port, uint8 event ) {
extern uint8 SampleApp_TaskID;
22
无线传感网络课程论文
rxlen=Hal_UART_RxBufLen(SERIAL_APP_PORT); //接收缓冲区数据长度 rbuf=osal_mem_alloc(rxlen+1); //分配缓冲区,多分配一个字节 rbuf[0]=rxlen; //第一个字节存放数据长度
HalUARTRead ( SERIAL_APP_PORT, rbuf+1, rxlen); //读接收缓冲区数据到rbuf if(!rxlen)
osal_mem_free( rbuf ); //释放内存 else
osal_set_event(SampleApp_TaskID,UART_RX_CB_EVT); //触发事件 }
说明:如果uart的buffer中有数据就会调用这个函数,这个函数的功能是利用Hal_UART_RxBufLen读取buffer中数据的长度,并将其放在rbuf[0]中。利用HalUARTRead读取buffer的数据放在buffer的其他位置。最后触发了UART_RX_CB_EVT事件。
? UART_RX_CB_EVT事件的处理(SampleApp.c)
if ( events & UART_RX_CB_EVT ) //串口有数据需要处理 {
SampleApp_SPI_SendData( rbuf, rxlen+1 ); //调用处理函数,将信息发送出去
return (events ^ UART_RX_CB_EVT); }
? SampleApp_SPI_SendData( rbuf, rxlen+1 )函数说明(SampleApp.c):
void SampleApp_SPI_SendData( uint8 *buf, uint8 len )
23
无线传感网络课程论文
{
SampleApp_SPI_SendData_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast; SampleApp_SPI_SendData_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_SPI_SendData_DstAddr.addr.shortAddr = 0xFFFF; if ( AF_DataRequest ( &SampleApp_SPI_SendData_DstAddr, (endPointDesc_t *)&SampleApp_epDesc, SAMPLEAPP_FLASH_CLUSTERID, len, buf,
&SampleApp_TransID, 0,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS ) {
osal_mem_free( rbuf ); //必须释放内存,不然造成溢出! } else {
osal_mem_free( rbuf ); //必须释放内存,不然造成溢出! } }
至此完成了数据从buffer中向空中发送的过程 下面是接受部分代码:
? 事件处理函数SampleApp_ProcessEvent(SampleApp.c):
if ( events & SYS_EVENT_MSG )//判断任务(一个任务可以有多个事件) {
while ( MSGpkt )//对比事件 { ??
case AF_INCOMING_MSG_CMD:
SampleApp_MessageMSGCB( MSGpkt ); break;
? SampleApp_MessageMSGCB( )函数说明(SampleApp.c):
void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt ) {
switch ( pkt->clusterId ) { ??
case SAMPLEAPP_FLASH_CLUSTERID://此clusterid由SampleApp_SPI_SendData函数发送数据
pointer1=&pkt->cmd.Data[1]; //接收数据指针,指向数据
HalUARTWrite(0,pointer1,pkt->cmd.Data[0]);//pkt->cmd.Data[0]是数据的大小 break;
24
无线传感网络课程论文
}
第五章 调试与分析
由于服务必须从服务控制管理器的上下文中运行,而不是从Visual Studio中运行,因此调试服务不像调试其他Visual Studio应用程序类型那样简单。若要调试服务,必须首先启动服务,然后将一个调试器附加到正在运行服务的进程中。然后可以使用 Visual Studio 的所有标准调试功能来调试应用程序。
附加到服务的进程能够调试大多数服务代码,但并非全部;例如,由于服务已经启动,因此不能用这种方法调试服务的 OnStart 方法中的代码,或调试用于加载服务的 Main 方法中的代码。
由于服务应用程序调试的特殊性,直接把服务应用程序里面的实际工作代码提取出来做成一般的应用程序,而后调试。这样更简单,直接。把调试好了的应用程序里面的代码放在服务里面就可以了。还有一种方法就是写日志文件。这也是调试服务的一个比较好的方法,虽然比较笨,但是通过阅读自己留下的日志,也能起到不小的作用的
25