Exemplo n.º 1
0
/**	@fn	void CEpollIOLoop::Run()
*	@brief 
*	@return	
*/
void CEpollIOLoop::Run()
{
	struct epoll_event ev;
	ev.data.fd=m_waker.GetWakeSocket();
	//设置要处理的事件类型
	ev.events=EPOLLIN;
	epoll_ctl(eid, EPOLL_CTL_ADD, &ev);

	while (True)
	{
		struct epoll_event events[EPOLL_SIZE];

		HPR_INT32 nfds = epoll_wait(m_eid, events, EPOLL_SIZE, -1);
		if (nfds <= 0)
			continue;

		for (HPR_INT32 i = 0; i < nfds; i++)
		{
			HPR_SOCKET sock = events[i].data.fd;
			if (sock == m_waker.GetWakeSocket())
			{
				m_waker.Recv();
			}
			else if (events[i].events & EPOLLIN)
			{
				CBaseIOStream* pIOStream = _GetHandlerBySock(sock);
				if (pIOStream != NULL)
				{
					if (pIOStream->GetSockType() == SOCK_TCP_SERVER)
					{
						pIOStream->OnAccept();
					}
					else
					{
						pIOStream->OnRecv();
					}
				}
				else
				{
					//调试的时候可能数据还没读,但是对象已经没了,需要清掉
					//貌似epoll会在调用close(sock)后会自己清除。
					//epoll_ctl(eid, EPOLL_CTL_DEL, &events[i]);
				}
			}
		}
	}
}
Exemplo n.º 2
0
/**	@fn	void CEpollIOLoop::Run()
*	@brief 
*	@return	
*/
void CEpollIOLoop::Run()
{
	struct epoll_event ev;
	ev.data.fd=m_waker.GetWakeSocket();
	//设置要处理的事件类型
	ev.events=EPOLLIN;
	epoll_ctl(m_eid, EPOLL_CTL_ADD, m_waker.GetWakeSocket(), &ev);

	while (TRUE)
	{
		struct epoll_event* events = new epoll_event[_GetEpollSize()];
		int32_t nfds = epoll_wait(m_eid, events, _GetEpollSize(), -1);
		if (nfds <= 0)
			continue;
		for (int32_t i = 0; i < nfds; i++)
		{
			S_SOCKET sock = events[i].data.fd;
			if (sock == m_waker.GetWakeSocket())
			{
				m_waker.Recv();
			}
			else if (events[i].events & EPOLLIN)
			{
				CBaseIOStream* pIOStream = _GetHandlerBySock(sock);
				if (pIOStream != NULL)
				{
					if (pIOStream->GetSockType() == SOCK_TCP_SERVER)
					{
						pIOStream->OnAccept();
					}
					else
					{
						pIOStream->OnRecv();
                        SOCKET_IO_TRACE("socket recv data, sock id: %d.", pIOStream->GetSocketID());
					}
				}
				else
				{
					//调试的时候可能数据还没读,但是对象已经没了,需要清掉
					//epoll也会在调用close(sock)后会自己清除。
					epoll_ctl(m_eid, EPOLL_CTL_DEL, sock, &events[i]);
				}
			}//EPOLLIN
			else if (events[i].events & EPOLLOUT)
			{
				CBaseIOStream* pIOStream = _GetHandlerBySock(sock);
				if (pIOStream != NULL)
				{
					if (pIOStream->GetSockType() == SOCK_TCP_CLIENT && pIOStream->CheckConnect())
					{
						//连接成功
						pIOStream->OnConnect(TRUE);
					}
					pIOStream->SendBufferAsync();
				}
			}//EPOLLOUT
			else if (events[i].events & EPOLLERR)
			{
				CBaseIOStream* pIOStream = _GetHandlerBySock(sock);
				if (pIOStream->GetSockType() == SOCK_TCP_CLIENT && pIOStream->CheckConnect())
				{
					int32_t nError, nCode;
					socklen_t nLen; 
					nLen = sizeof(nError);     
					nCode = getsockopt(pIOStream->GetSocket(), SOL_SOCKET, SO_ERROR, &nError, &nLen);
					if (nCode < 0 || nError) 
					{     
						//连接失败
						SOCKET_IO_WARN("socket connect failed, nCode: %d, nError: %d.", nCode, nError);
						pIOStream->OnConnect(FALSE);
					}
				}
			}//EPOLLERR
		}
	}
}
Exemplo n.º 3
0
/**	@fn	void CIOLoop::Run()
*	@brief
*	@return
*/
void CIOLoop::Run()
{
    fd_set fd_read;
    while (m_bCloseRequest == HPR_FALSE)
    {
        HPR_INT32 nSockNum = 0;
        HPR_INT32 nMaxfd = 0;
        FD_ZERO(&fd_read);
        FD_SET(m_waker.GetWakeSocket(), &fd_read);
        if(m_waker.GetWakeSocket() > nMaxfd)
            nMaxfd = m_waker.GetWakeSocket();
        nSockNum++;
        m_MapMutex.Lock();
        map<HPR_SOCK_T, CBaseIOStream*> mapTmp = m_MapIOStreamBySocket;
        m_MapMutex.Unlock();
        map<HPR_SOCK_T, CBaseIOStream*>::iterator it = mapTmp.begin();
        for (; it != mapTmp.end(); it++)
        {
            FD_SET(it->first, &fd_read);
            if(it->first > nMaxfd)
                nMaxfd = it->first;
            nSockNum++;
        }
        timeval tv;
        tv.tv_sec = 10;
        tv.tv_usec = 0;
        HPR_INT32 nRet = HPR_Select(nMaxfd + 1, &fd_read, NULL, NULL, NULL);
        if (nRet > 0)
        {
            if (HPR_FdIsSet(m_waker.GetWakeSocket(), &fd_read))
            {
                //stop
                m_waker.Recv();
            }
            else
            {
                map<HPR_SOCK_T, CBaseIOStream*>::iterator it1 = mapTmp.begin();
                for (; it1 != mapTmp.end(); it1++)
                {
                    if (HPR_FdIsSet(it1->first, &fd_read))
                    {
                        CBaseIOStream* pIOStream = _GetHandlerBySock(it1->first);
                        if (pIOStream != NULL)
                        {
                            if (pIOStream->GetSockType() == SOCK_TCP_SERVER)
                            {
                                pIOStream->OnAccept();
                            }
                            else
                            {
                                pIOStream->OnRecv();
                            }
                        }
                    }
                }
            }
        }
        else
        {

            //TODO
            //Error
        }

    }
}
Exemplo n.º 4
0
/**	@fn	void CIOLoop::Run()
*	@brief 
*	@return	
*/
void CIOLoop::Run()
{
	fd_set fd_read, fd_write, fd_error;
	while (m_bCloseRequest == FALSE)
	{
		int nMaxfd = 0;
		FD_ZERO(&fd_read);
		FD_ZERO(&fd_write);
		FD_ZERO(&fd_error);
		FD_SET(m_waker.GetWakeSocket(), &fd_read);
		if(m_waker.GetWakeSocket() > nMaxfd) 
			nMaxfd = m_waker.GetWakeSocket();
		m_MapMutex.Lock();
		map<S_SOCKET, CBaseIOStream*> mapTmp = m_MapIOStreamBySocket;
		m_MapMutex.Unlock();
		map<S_SOCKET, CBaseIOStream*>::iterator it = mapTmp.begin();
		for (; it != mapTmp.end(); it++)
		{
			CBaseIOStream* pIOStream = it->second;
			if (pIOStream->CheckConnect() == FALSE)
			{
				//如果是要检查TCP CLIENT是否连接,则不设置可读
				FD_SET(it->first, &fd_read);
				if(it->first > nMaxfd) 
					nMaxfd = it->first;
			}
			if (pIOStream->CheckWrite() == TRUE)
			{
				//设置可写
				FD_SET(it->first, &fd_write);
				if(it->first > nMaxfd) 
					nMaxfd = it->first;
				//设置错误信号,用于windows的tcp connect超时检查,同时查看是否有其他触发错误
				FD_SET(it->first, &fd_error);
			}
		}
		timeval tv;
		tv.tv_sec = 1;
		tv.tv_usec = 0;
		int nRet = select(nMaxfd + 1, &fd_read, &fd_write, &fd_error, NULL);
		if (nRet > 0)
		{
			if (FD_ISSET(m_waker.GetWakeSocket(), &fd_read))
			{
				//stop
				m_waker.Recv();
			}
			map<S_SOCKET, CBaseIOStream*>::iterator it1 = mapTmp.begin();
			for (; it1 != mapTmp.end(); it1++)
			{
				//read
				if (FD_ISSET(it1->first, &fd_read))
				{
					CBaseIOStream* pIOStream = _GetHandlerBySock(it1->first);
					if (pIOStream != NULL)
					{
						if (pIOStream->GetSockType() == SOCK_TCP_SERVER)
						{
							pIOStream->OnAccept();
						}
						else
						{
							pIOStream->OnRecv();
						}	
					}
				}//read
				//write
				if (FD_ISSET(it1->first, &fd_write))
				{
					CBaseIOStream* pIOStream = _GetHandlerBySock(it1->first);
					if (pIOStream != NULL)	
					{
						if (pIOStream->GetSockType() == SOCK_TCP_CLIENT && pIOStream->CheckConnect())
						{
#if (defined(_WIN32) || defined(_WIN64))
							pIOStream->OnConnect(TRUE);
//#elif defined(__linux__) //mac???
#else
							//这个是unix的处理方式,经测试linux也适用,mac同理
							int32_t nError, nCode;
							socklen_t nLen; 
							nLen = sizeof(nError);     
							nCode = getsockopt(pIOStream->GetSocket(), SOL_SOCKET, SO_ERROR, &nError,
                                               &nLen);
							if (nCode < 0 || nError) 
							{     
								//连接失败
								//linux的超时失败是也是根据这个可以判断
								SOCKET_IO_WARN("socket connect failed, nCode: %d, nError: %d.", nCode,
                                               nError);
								pIOStream->OnConnect(FALSE);
							}
							else
							{
								//连接成功
								//SOCKET_IO_WARN("socket connect successed.", nCode, nError);
								pIOStream->OnConnect(TRUE);
							}
#endif
						}
						pIOStream->SendBufferAsync();
					}
				}//wirte
				//error
				if (FD_ISSET(it1->first, &fd_error))
				{
					CBaseIOStream* pIOStream = _GetHandlerBySock(it1->first);
					if (pIOStream != NULL)
					{
						//windows的超时判断是利用err_fds来判断
						//对于不存在的IP(即linux会报111错误),或者IP存在,端口不存在(即linux会报110错误)
						//都是超时错误
						if (pIOStream->CheckConnect() == TRUE)
						{
							SOCKET_IO_WARN("socket connect time out, remote ip: %s, port: %d.",
                                           pIOStream->GetRemoteIP(), pIOStream->GetRemotePort());
							pIOStream->OnConnect(FALSE);
						}
						else
						{
							SOCKET_IO_WARN("err_fds, %d.", (int32_t)pIOStream->GetSockType());
						}
					}
				}//error
			}//for
		}// nRet > 0
		else if (0 == nRet)
		{
			//Time Out
			//map<HPR_SOCK_T, CBaseIOStream*>::iterator it1 = mapTmp.begin();
			//for (; it1 != mapTmp.end(); it1++)
			//{
			//	//write
			//	CBaseIOStream* pIOStream = _GetHandlerBySock(it1->first);
			//	if (pIOStream != NULL)
			//	{
			//		if (pIOStream->GetSockType() == SOCK_TCP_CLIENT && pIOStream->CheckConnect())
			//		{
			//		}
			//	}
			//}
		}
		else
		{
			//TODO
			//Error
			SOCKET_IO_ERROR("socket select error");
            break;
		}
	}
}