www.pudn.com > goodchessGame.zip > FiveInOneSocket.cpp
#include "stdafx.h"
#include "FiveInOneSocket.h"
#include "FiveInOne.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const int nMessageID = WM_USER + 342;
CFiveInOneSocket::CFiveInOneSocket(void)
{
}
CFiveInOneSocket::CFiveInOneSocket(HWND Wnd)
{
WORD wVersionRequested = 0x202;
if (0 != WSAStartup(wVersionRequested, &m_WinsockData))
{
AfxMessageBox(_T("Could not start WinSock"));
}
m_hKillEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
m_hSentEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
m_hReadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
m_Socket = INVALID_SOCKET;
m_HWnd = Wnd;
m_pThread = NULL;
}
CFiveInOneSocket::~CFiveInOneSocket(void)
{
SetEvent(m_hKillEvent);
WaitForSingleObject(m_pThread->m_hThread, INFINITE);
CloseHandle(m_hKillEvent);
CloseHandle(m_hSentEvent);
CloseHandle(m_hReadEvent);
closesocket(m_Socket);
}
BOOL CFiveInOneSocket::Connect(CString & str)
{
// Set up the socket
if ((m_Socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
return false;
}
hostent *hent = gethostbyname(str.GetBuffer());
if(hent == NULL)
return FALSE;
m_SockAddrIn.sin_addr.s_addr = *((unsigned long*)(hent->h_addr));
m_SockAddrIn.sin_family = AF_INET;
m_SockAddrIn.sin_port = htons(short(9876));
if(connect(m_Socket, (sockaddr *)&m_SockAddrIn, sizeof(m_SockAddrIn)) == SOCKET_ERROR)
{
closesocket(m_Socket);
return false;
}
return true;
}
void CFiveInOneSocket::StartThread()
{
m_pThread = AfxBeginThread(ThreadProc, this);
}
UINT CFiveInOneSocket::ThreadProc(LPVOID pParam)
{
CFiveInOneSocket *pThis = (CFiveInOneSocket*)pParam;
if(pThis)
{
while(WaitForSingleObject(pThis->m_hKillEvent,0) != WAIT_OBJECT_0)
{
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_HWnd, nMessageID, CFiveInOneSocket::kCanBeRead, 0);
}
}
if(WaitForSingleObject(pThis->m_hSentEvent, 0) != WAIT_OBJECT_0)
{
iRC2 = select(0, NULL, &fds2, NULL, &ReceiveTimeout);
if(iRC2 < 0)
break;
if(iRC2 > 0)
SetEvent(pThis->m_hSentEvent);
}
}
}
return 0;
}
BOOL CFiveInOneSocket::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 CFiveInOneSocket::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;
}
}
}