监视UDP报文的一个类
发布时间:2021-07-06 05:56:42 所属栏目:大数据 来源: https://www.jb51.cc
导读:目标是用winsock2完成对UDP报文的监视 。 UDP报文属于一种无连接的报文传送机制,所以发送速度快,如果没有报文次序的要求,应该属于一种很好的网络通讯方式。 为了实现对UDP报文的监视,我开了一个线程,专门用于等待UDP报文的到达信息,其中采用winsock I/
|
目标是用winsock2完成对UDP报文的监视。
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;
}
? (编辑:北几岛) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
