加入收藏 | 设为首页 | 会员中心 | 我要投稿 北几岛 (https://www.beijidao.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

监视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;

}
?

(编辑:北几岛)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读