BaseSocketReceiveThread.cpp 3.39 KB
#include "BaseSocketReceiveThread.h"
#include "BaseSocket.h"
#include <unistd.h>

CBaseSocketReceiveThread::CBaseSocketReceiveThread()
{
	m_pSocket = NULL;
}

CBaseSocketReceiveThread::~CBaseSocketReceiveThread()
{
}

BOOL CBaseSocketReceiveThread::InitInstance()
{
	// TODO:  perform and per-thread initialization here
	while (m_pSocket == NULL)
		sleep(1);

	return CBaseThread::InitInstance();
}

int CBaseSocketReceiveThread::ExitInstance()
{
	// TODO:  perform any per-thread cleanup here
	return CBaseThread::ExitInstance();
}

int CBaseSocketReceiveThread::Run()
{
	// TODO: Add your specialized code here and/or call the base class
	BOOL bExit = FALSE;
	while (!bExit)
	{
		TreatSocketEvents();
		if (IsStopping(0))
		{
			bExit = TRUE;
		}
	}

	return ExitInstance();
}

void CBaseSocketReceiveThread::SetSocket(CBaseSocket *pSocket)
{
	m_pSocket = pSocket;
}

void CBaseSocketReceiveThread::TreatSocketEvents(long lTimeOut)
{
	int errorVal;
	socklen_t errorLen;
	errorLen = sizeof(int);
	timeval interval;
	interval.tv_sec = 0;
	interval.tv_usec = lTimeOut * 1000;
	fd_set fdReadSet;
	fd_set fdWriteSet;
	FD_ZERO(&fdReadSet);
	FD_ZERO(&fdWriteSet);
	switch (m_pSocket->GetStatus())
	{
	case BASE_SOCKET_STATUS_LISTENNING:
	case BASE_SOCKET_STATUS_CONNECTED:
		FD_SET(m_pSocket->m_hSocket, &fdReadSet);
		break;
	case BASE_SOCKET_STATUS_CONNECTING:
		FD_SET(m_pSocket->m_hSocket, &fdReadSet);
		FD_SET(m_pSocket->m_hSocket, &fdWriteSet);
		break;
	default:
		break;
	}

	if (select(FD_SETSIZE, &fdReadSet, &fdWriteSet, NULL, &interval) < 0)
	{
		CONSOLE_LOG("select < 0\n");
	}
	else
	{
		switch (m_pSocket->GetStatus())
		{
		case BASE_SOCKET_STATUS_LISTENNING:
		{
			if (FD_ISSET(m_pSocket->m_hSocket, &fdReadSet))
			{
				m_pSocket->OnAccept(errno);
			}
		}
			break;
		case BASE_SOCKET_STATUS_CONNECTED:
		{
			if (FD_ISSET(m_pSocket->m_hSocket, &fdReadSet))
			{
				if (getsockopt(m_pSocket->m_hSocket, SOL_SOCKET, SO_ERROR, &errorVal, &errorLen) == 0)
				{
					if (errorVal == 0)
					{
						m_pSocket->OnReceive(errno);
						if (m_pSocket->NothingIsReceived())
						{
							CONSOLE_LOG("nothing is received \n");
							m_pSocket->SetStatus(BASE_SOCKET_STATUS_CREATED);
							m_pSocket->OnClose(errno);
						}
					}
					else
					{
						CONSOLE_LOG("error when receive \n");
						m_pSocket->OnClose(errno);
						m_pSocket->SetStatus(BASE_SOCKET_STATUS_DISCONNECTED);
					}
				}
				else
				{
					CONSOLE_LOG("getsocketopt failed!\n"); CONSOLE_LOG("errno is %s. \n", strerror(errno));
				}
			}
		}
			break;
		case BASE_SOCKET_STATUS_CONNECTING:
		{
			if (FD_ISSET(m_pSocket->m_hSocket, &fdWriteSet))
			{
				if (getsockopt(m_pSocket->m_hSocket, SOL_SOCKET, SO_ERROR, &errorVal, &errorLen) == 0)
				{
					if (errorVal == 0)
					{
						m_pSocket->OnConnect(0);
						m_pSocket->SetStatus(BASE_SOCKET_STATUS_CONNECTED);
					}
					else
					{
						m_pSocket->OnConnect(-1);
						m_pSocket->SetStatus(BASE_SOCKET_STATUS_DISCONNECTED);
					}
				}
				else
				{
					CONSOLE_LOG("getsocketopt failed!\n"); CONSOLE_LOG("errno is %s. \n", strerror(errno));
				}
			}
			else if (FD_ISSET(m_pSocket->m_hSocket, &fdReadSet))
			{
				m_pSocket->OnConnect(-1);
				m_pSocket->SetStatus(BASE_SOCKET_STATUS_DISCONNECTED);
			}
		}
			break;
		default:
			break;
		}

	}
}