www.pudn.com > goodchessGame.zip > ListeningSocket.cpp


#include "stdafx.h" 
#include "ListeningSocket.h" 
#include "ClientSocket.h" 
#include "FiveInOne.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
CListeningSocket::CListeningSocket(void) 
{ 
} 
 
CListeningSocket::CListeningSocket(HWND Wnd) 
{ 
	WORD wVersionRequested = 0x202; 
 
	if (0 != WSAStartup(wVersionRequested, &m_WinsockData)) 
	{ 
		AfxMessageBox(_T("Could not start WinSock")); 
	} 
	 
	m_pThread = NULL; 
	m_hKillEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 
	m_hAllConnectedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);	 
	m_hSentEvent = CreateEvent(NULL, TRUE, TRUE, NULL); 
    
	m_Socket = INVALID_SOCKET; 
	 
	m_HWnd = Wnd; 
	m_nCounter = 0; 
} 
 
CListeningSocket::~CListeningSocket(void) 
{ 
	SetEvent(m_hKillEvent); 
 
	POSITION pos = m_ConnectionList.GetHeadPosition(); 
	while(pos != NULL) 
	{ 
		CClientSocket *pSocket = (CClientSocket*)m_ConnectionList.GetNext(pos); 
		WaitForSingleObject(pSocket->m_pThread->m_hThread, INFINITE); 
		delete pSocket; 
	} 
	m_ConnectionList.RemoveAll(); 
 
	WaitForSingleObject(m_pThread->m_hThread, INFINITE); 
	 
	CloseHandle(m_hKillEvent); 
	CloseHandle(m_hAllConnectedEvent);	 
	CloseHandle(m_hSentEvent); 
	    
	closesocket(m_Socket); 
 
	::WSACleanup(); 
} 
 
void CListeningSocket::StartThread() 
{ 
	m_pThread = AfxBeginThread(ThreadProc, this); 
} 
 
BOOL CListeningSocket::Listen(int port) 
{ 
	// Set up the socket
	if ((m_Socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) 
	{
		return false;
	}

	// Set up socket info structure
	m_SockAddrIn.sin_addr.s_addr = htonl(INADDR_ANY);
	m_SockAddrIn.sin_family = AF_INET;
	m_SockAddrIn.sin_port = htons(short(port));

	// Bind the socket to an appropriate port and interface
	if (bind(m_Socket, (sockaddr *)&m_SockAddrIn, sizeof(m_SockAddrIn)) == SOCKET_ERROR)
	{
		closesocket(m_Socket);
		return false;
	}

	// Listen on socket -- use Winsock's max of 5 pending connections
	if (listen(m_Socket, 5) == SOCKET_ERROR)
	{
		closesocket(m_Socket);
		return false;
	}

	u_long lg = 1U;
	if(ioctlsocket(m_Socket, FIONBIO, &lg) < 0)
	{
		closesocket(m_Socket);
		return false;
	}

    return true; 
} 
 
UINT CListeningSocket::ThreadProc(LPVOID pParam) 
{ 
	CListeningSocket *pthis = (CListeningSocket*)pParam; 
	 
	if(pthis) 
	{ 
		while(WaitForSingleObject(pthis->m_hKillEvent, 0) != WAIT_OBJECT_0) 
		{ 
			SOCKET temp = accept(pthis->m_Socket, NULL, NULL); 
            if(temp == INVALID_SOCKET) 
			{ 
				if(WaitForSingleObject(pthis->m_hKillEvent, 0) == WAIT_OBJECT_0) 
					break; 
			} 
			else 
			{ 
				pthis->m_nCounter++; 
				CClientSocket *pClientSocket = new CClientSocket(pthis, temp); 
				pClientSocket->m_SocketID = pthis->m_nCounter; 
				pthis->m_ConnectionList.AddHead(pClientSocket); 
				pClientSocket->StartThread(); 
                 
				if(pthis->m_nCounter >= FIVEINONE_APP->m_pGameController->m_Dlg.m_nNumOfPlayers + 1) 
				{ 
					SetEvent(pthis->m_hAllConnectedEvent); 
					break; 
				} 
			} 
		} 
	} 
	return 0; 
}