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;
}