www.pudn.com > goodchessGame.zip > ClientSocket.cpp
#include "stdafx.h"
#include "clientsocket.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const int nMessageID = WM_USER + 342;
CClientSocket::CClientSocket(void)
{
}
CClientSocket::CClientSocket(CListeningSocket *pListeningSocket, SOCKET Socket)
{
m_pThread = NULL;
m_pListeningSocket = pListeningSocket;
m_Socket = Socket;
m_bSentReady = TRUE;
m_SocketID = 0;
m_hReadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
}
CClientSocket::~CClientSocket(void)
{
CloseHandle(m_hReadEvent);
closesocket(m_Socket);
}
void CClientSocket::StartThread()
{
m_pThread = AfxBeginThread(ThreadProc, this);
}
UINT CClientSocket::ThreadProc(LPVOID pParam)
{
CClientSocket *pThis = (CClientSocket*)pParam;
if(pThis)
{
while(WaitForSingleObject(pThis->m_pListeningSocket->m_hKillEvent,0) != WAIT_OBJECT_0)
{
//WaitForSingleObject(pThis->m_pListeningSocket->m_hAllConnectedEvent, INFINITE);
int iRC = 0;
int iRC2 = 0;
timeval ReceiveTimeout;
// Set timeout
ReceiveTimeout.tv_sec = 0;
ReceiveTimeout.tv_usec = 250000; // 250 ms
fd_set fds;
FD_ZERO(&fds);
FD_SET(pThis->m_Socket, &fds);
fd_set fds2;
FD_ZERO(&fds2);
FD_SET(pThis->m_Socket, &fds2);
if(WaitForSingleObject(pThis->m_hReadEvent, 0) != WAIT_OBJECT_0)
{
iRC = select(0, &fds, NULL, NULL, &ReceiveTimeout);
if(iRC < 0)
{
break;
}
if(iRC > 0)
{
SetEvent(pThis->m_hReadEvent);
::PostMessage(pThis->m_pListeningSocket->m_HWnd, nMessageID, CListeningSocket::kCanBeRead, pThis->m_SocketID);
}
}
if(!pThis->m_bSentReady)
{
iRC2 = select(0, NULL, &fds2, NULL, &ReceiveTimeout);
if(iRC2 < 0)
{
break;
}
if(iRC2 > 0)
pThis->m_bSentReady = TRUE;
}
int counter = 0;
POSITION pos = pThis->m_pListeningSocket->m_ConnectionList.GetHeadPosition();
while(pos != NULL)
{
CClientSocket *pSocket = (CClientSocket*)pThis->m_pListeningSocket->m_ConnectionList.GetNext(pos);
if(pSocket->m_bSentReady)
counter++;
}
if(WaitForSingleObject(pThis->m_pListeningSocket->m_hSentEvent, 0) != WAIT_OBJECT_0)
{
if(counter == pThis->m_pListeningSocket->m_ConnectionList.GetCount())
SetEvent(pThis->m_pListeningSocket->m_hSentEvent);
}
}
}
ResetEvent(pThis->m_pListeningSocket->m_hAllConnectedEvent);
if(WaitForSingleObject(pThis->m_pListeningSocket->m_hKillEvent,0) != WAIT_OBJECT_0)
{
POSITION ps = pThis->m_pListeningSocket->m_ConnectionList.GetHeadPosition();
while (ps != NULL)
{
POSITION temp = ps;
CClientSocket *pSocket = (CClientSocket*)pThis->m_pListeningSocket->m_ConnectionList.GetNext(ps);
if(pSocket == pThis)
{
pThis->m_pListeningSocket->m_ConnectionList.RemoveAt(temp);
delete pSocket;
}
}
}
return 0;
}
BOOL CClientSocket::Read(char *pBuffer, int nLen)
{
int iReceiveStatus = 0;
char *pLocalBuffer = static_cast(pBuffer);
while(nLen > 0)
{
iReceiveStatus = recv(m_Socket, pLocalBuffer, nLen, 0);
// Error
if(iReceiveStatus <= 0)
{
closesocket(m_Socket);
return FALSE;
}
else
{
// Update buffer and counter
nLen -= iReceiveStatus;
pLocalBuffer += iReceiveStatus;
}
int iRC = 0;
timeval ReceiveTimeout;
// Set timeout
ReceiveTimeout.tv_sec = 0;
ReceiveTimeout.tv_usec = 250000; // 250 ms
fd_set fds;
FD_ZERO(&fds);
FD_SET(m_Socket, &fds);
iRC = select(0, &fds, NULL, NULL, &ReceiveTimeout);
if(iRC == 0)
break;
else if(iRC < 0)
{
closesocket(m_Socket);
return FALSE;
}
}
return TRUE;
}
void CClientSocket::Write(char *pBuffer, int nLen)
{
int iSendStatus = 0;
char *pLocalBuffer = static_cast(pBuffer);
// As long as we need to receive bytes...
while(nLen > 0)
{
// Receive some bytes
iSendStatus = send(m_Socket, pLocalBuffer, nLen, 0);
// Error
if(iSendStatus < 0)
return;
else
{
// Update buffer and counter
nLen -= iSendStatus;
pLocalBuffer += iSendStatus;
}
}
}