UDP报文属于一种无连接的报文传送机制,所以发送速度快,如果没有报文次序的要求,应该属于一种很好的网络通讯方式。
为了实现对UDP报文的监视,我开了一个线程,专门用于等待UDP报文的到达信息,其中采用winsock I/O模型中的select异步模型-WSAEventSelect。
该模型最主要的特点是在网络事件发生时会投递一个事件对象句柄。
其中初始化winsock,注册select模型的的方法如下: 代码:
//建立一个网络事件发生时要投递的事件对象 m_socketEvent=WSACreateEvent(); //选择异步socket模型 ::WSAEventSelect(m_sock,m_socketEvent,FD_READ);实现监视守护线程 代码:
UINT CUdpProc::UDPListen( LPVOID pParam ){ CUdpProc* proc=(CUdpProc*)pParam; //投递的网络事件 WSANETWORKEVENTS networkEvents; DWORD dCount=1; //给主线程预留的管理事件,以关闭本线程 while(::WaitForSingleObject(proc->m_event.m_hObject,300)!=WAIT_OBJECT_0) { if(proc->m_socketEvent==WSA_INVALID_EVENT) { break; } //阻塞UDP监听 ::WSAWaitForMultipleEvents(dCount,&(proc->m_socketEvent),FALSE,WSA_INFINITE,FALSE); //事件到达后的处理 ::WSAEnumNetworkEvents(proc->m_sock,proc->m_socketEvent,&networkEvents); if(networkEvents.lNetworkEvents & FD_READ) //如果是数据到达 { if(networkEvents.IErrorCode[FD_READ_BIT]!=0) { TRACE("err code=%d/n",networkEvents.IErrorCode[FD_READ_BIT]); } else proc->DoMsgRead(); //处理数据 } //重新设置投递的事件对象 ::WSAresetEvent(proc->m_socketEvent); } //告诉主线程,监听线程结束 proc->m_eventListenClose.SetEvent(); return 0L;}
由于子线程大部分时间处于阻塞状态,不会响应主线程发送的事件信号,所以关闭监视子线程的方法采取如下措施: 代码:
//等待监听线程结束的事件信号 while(::WaitForSingleObject(m_eventListenClose.m_hObject,50)!=WAIT_OBJECT_0) { //设置关闭线程事件 m_event.pulseEvent(); //设置激活socket事件 ::WSASetEvent(m_socketEvent); //设置取消监视事件 ::WSAEventSelect(m_sock,0); } //释放监视事件 ::WSACloseEvent(m_socketEvent); m_event.Unlock(); m_eventListenClose.Unlock(); if(m_sock!=INVALID_SOCKET) { ::closesocket(m_sock); ::WSACleanup(); }启动线程的方法很简单, 代码:
BOol CUdpProc::StartListen(){ BOol bResult=InitSock(); AfxBeginThread(UDPListen,this); return bResult;}总结
以上是内存溢出为你收集整理的监视UDP报文的一个类全部内容,希望文章能够帮你解决监视UDP报文的一个类所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)