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