⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clientsocket.cpp

📁 wince 下socket实现的HTTP类
💻 CPP
字号:
/*******************************************************************************
* (C) Copyright 2008 Giant Electronics LTD 
* 
* These computer program listings and specifications are the property of Giant 
* Electronics LTD and shall not be reproduced or copied or used in whole or in 
* part without written permission from Giant Electronics LTD .
*
* Project:      IViewer 
* File Name:	ClientSocket.h 
* Programer(s):	Ben Zhan
* Created:      20080729 
* Description:	implementation of encapsulating Wince Socket APIs
* This class encapsulates the wince Socket API.
*******************************************************************************/

#include "stdafx.h"
#include "ClientSocket.h"



#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////



CClientSocket::CClientSocket()
{
	m_hSocket      = NULL;

	//m_hAysnEvent
	m_dwConnectTimeout = 10000; //默认非阻塞连接超时为10秒
	m_dwRecvTimeout = 6000;
	m_dwSendTimeout = 6000;
	m_lEventSelected = 0; 
	m_hWnd			= NULL;
	m_bBlock = TRUE;
	
}

BOOL	CClientSocket::SocketInit()
{
	WSADATA wsData;
	int nResult=WSAStartup(MAKEWORD(1,1),&wsData);
    if(nResult !=0)
    {
        return FALSE ;
    }
	return TRUE ; 
}

CClientSocket::~CClientSocket()
{
	Disconnect();
}
void CClientSocket::Disconnect(void)
{
	try
	{
		if (m_hSocket)
		{
			// Terminate receiving and sending thread if necessary
			closesocket(m_hSocket);
			m_hSocket = NULL;
		}
	}
	catch(...)
	{
		LUIS_TRACE(L"CClientSocket::Disconnect");
	}
}
// Attach a connected sockt to this object
bool CClientSocket::Attach(SOCKET inSock)
{
	if (m_hSocket != NULL)
		return false;

	m_hSocket = inSock;
	return true;
}

SOCKET CClientSocket::Detach(void)
{
	SOCKET hSock = m_hSocket;
	m_hSocket    = NULL;
	return hSock;
}

int CClientSocket::recv(char * outBuf , int nlen)
{
	return ::recv(m_hSocket, outBuf, nlen, 0);
}
int CClientSocket::Receive(char * outBuf, int inLen)
{
	if(!m_hSocket)
		return E_SOCKET_FAIL;
	// Check socket for readability 
	TIMEVAL tv;
	tv.tv_sec  = 0;
	tv.tv_usec = 0;
	fd_set rfds;
	while(true)
	{	
		FD_ZERO(&rfds);
		FD_SET(m_hSocket, &rfds);
		if (select(1, &rfds, NULL, NULL,&tv))
		{
			int    nCount = inLen;
			int    lenret = 0;
			char * pBuf   = outBuf;
			do 
			{
				lenret = ::recv(m_hSocket, pBuf, nCount, 0);
				if (lenret == SOCKET_ERROR) 
				{
					return E_SOCKET_FAIL;
				}
				else if (lenret == 0)
				{
					// Indicate the socket disconnected
					return E_SOCKET_CLOSE;
				}
				nCount -= lenret;
				pBuf   += lenret;
				if (nCount > 0) 
					Sleep(20);
			} while (nCount > 0);
			return S_SOCKET_OK;
		}
		else
		{
			// The socket not ready to read
			continue;
		}
	}
	return E_SOCKET_FAIL;
}

int CClientSocket::Send(const char * pData, int inLen)
{
	if (!m_hSocket || !pData)
		return E_SOCKET_FAIL;
	
	int nret   = 0;
	int nCount = inLen;
	do 
	{
		if (WaitForSocket(WAIT_SEND,20) != S_SOCKET_OK)
			return E_SOCKET_FAIL;

		nret = send(m_hSocket, pData, nCount, 0);
		if (nret == SOCKET_ERROR)
		{
			return E_SOCKET_FAIL;
		}
		nCount -= nret;
		pData  += nret;
	} 
	while (nCount > 0);
	return S_SOCKET_OK;

	return E_SOCKET_FAIL;
}

//modified by Ben 2009-01-05   support cancel event
//Connect to the remote socket
bool CClientSocket::Connect(LPCSTR lpszTarget, int iPort, HANDLE hCancelEvent/*=NULL*/)
{
	Disconnect();
	// Create a new socket to connection
	m_hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (m_hSocket == INVALID_SOCKET)
	{
		m_hSocket = NULL;
		return false;
	}
	// Resolve hostname
	DWORD  addr = inet_addr(lpszTarget);
	if (addr == INADDR_NONE) 
	{
		struct hostent *he = NULL ;
		int ntrytimes = 0 ;
		he = gethostbyname(lpszTarget); 
		while (he == NULL && ntrytimes < 2)
		{
			ntrytimes ++;
			he = gethostbyname(lpszTarget); 				
		}
			
		if (he == NULL) 
		{
			LUIS_TRACE(L"Socket couldn't look up host\n");
			closesocket(m_hSocket);
			m_hSocket = NULL;
			return false;
		}
		addr = *(DWORD *)(he->h_addr_list[0]);
	}



	if (m_bBlock != TRUE) //设置非阻塞方式连接
	{		
		ULONG temp = 1;
		UINT32 ret = 0;
		ret = ::ioctlsocket(m_hSocket, FIONBIO, &temp);
	}
/*
	if( m_lEventSelected != 0 && m_hWnd!=NULL )
	{
		int nRet = ::WSAAsyncSelect (m_hSocket, m_hWnd, WM_CLIENTSOCKET, m_lEventSelected) ;
		if( nRet==SOCKET_ERROR )
		{
			DWORD dwError = WSAGetLastError();
		}
	}
*/

	BOOL sopt = TRUE;	
	setsockopt(m_hSocket, IPPROTO_TCP, TCP_NODELAY, (char *)&sopt, sizeof(BOOL));
	setsockopt(m_hSocket, SOL_SOCKET, SO_DONTLINGER, (char *)&sopt, sizeof(BOOL));

	//set Recv and Send time out
	//设置发送超时
/*
	available in Microsoft implementation of Windows Sockets 2

	if(::setsockopt(m_hSocket,SOL_SOCKET,SO_SNDTIMEO,(char *)&m_dwSendTimeout,sizeof(m_dwSendTimeout))==SOCKET_ERROR)
	{
		DWORD dwError = WSAGetLastError();
		return false;	
	}

	//设置接收超时
	if(::setsockopt(m_hSocket,SOL_SOCKET,SO_RCVTIMEO,(char *)&m_dwRecvTimeout,sizeof(m_dwSendTimeout))==SOCKET_ERROR)
	{
		DWORD dwError = WSAGetLastError();
		return false;	
	}
*/
	

	// Create socket address
	SOCKADDR_IN   saddr;
	memset(&saddr, 0, sizeof(SOCKADDR_IN));
	saddr.sin_addr.S_un.S_addr = addr;
	saddr.sin_family           = AF_INET;
	saddr.sin_port             = htons((WORD)iPort);

	// Connect to the remote host

	int nRet ;
	nRet = connect(m_hSocket, (SOCKADDR *)&saddr, sizeof(SOCKADDR_IN));	
	if (nRet == SOCKET_ERROR)
	{	
		DWORD dwError = WSAGetLastError();

		if (m_bBlock == FALSE && dwError == WSAEWOULDBLOCK)
		{
			nRet = WaitForSocket(WAIT_CONNECT,m_dwConnectTimeout/1000,hCancelEvent);
			
			if (nRet == S_SOCKET_OK)
			{
				//连接成功,设回阻塞模式方便处理接收与发送,否则一般的recv send很难控制
				ULONG temp = 0;
				UINT32 ret = 0;
				ret = ::ioctlsocket(m_hSocket, FIONBIO, &temp);
				return true;
			}	
		}

		closesocket(m_hSocket);
		m_hSocket = NULL;
		return false;
	}
	else if (nRet != 0) 
	{
		closesocket(m_hSocket);
		m_hSocket = NULL;
		return false;
	}
	return true;
}


int CClientSocket::WaitForSocket(WAIT_TYPE waitType,int nSecs,HANDLE hCancelEvent)
{
	int nRet = E_SOCKET_TIMEOUT;	
	
	int nTryTimes = 0;
	
	TIMEVAL tm;
	tm.tv_sec  = 1;
	tm.tv_usec = 0;
	FD_SET fds;

	if (!hCancelEvent)
	{//no cancel event then waitting one times
		tm.tv_sec  = nSecs;	
		nSecs = 1;
	}
	else	
		tm.tv_sec  = 1;

	while(nTryTimes < nSecs)
	{
		nTryTimes ++;		
		if (hCancelEvent && WaitForSingleObject(hCancelEvent,0) == WAIT_OBJECT_0)
		{
			nRet = E_SOCKET_CANCEL;
			break;
		}
		
		
		FD_ZERO(&fds);
		FD_SET(m_hSocket, &fds);

		int	nRes;
		switch(waitType)
		{
		case WAIT_CONNECT:
			nRes = ::select(0, 0, &fds, NULL, &tm);
			break;
		case WAIT_SEND:
			nRes = ::select(0, NULL, &fds, NULL, &tm);
			break;
		case WAIT_RECV:
			nRes = ::select(0, &fds, NULL, NULL, &tm);
			break;
		}
		if (nRes == SOCKET_ERROR)
		{ 
			DWORD dwRes=WSAGetLastError();
			TRACE(L"\nselect recv status errorcode=%d\n",dwRes);
		}
		else if (nRes > 0)
		{
			nRet = S_SOCKET_OK;
			break;		
		}
	}	
	return nRet;
}


//设置阻塞状态,true为阻塞

void CClientSocket::SetBlock(BOOL bBlock)
{
	if( m_bBlock == bBlock )
		return ;
	m_bBlock = bBlock ; 
}

void	CClientSocket::AsyncSelect(long lEvent , HWND hWnd)
{	
	ASSERT (hWnd) ;
	m_lEventSelected = lEvent ; 
	m_hWnd = hWnd ;

}

void CClientSocket::SetRecvTimeout(DWORD dwTime/*=10000 默认10秒*/)
{
	m_dwRecvTimeout = dwTime;
}
void CClientSocket::SetSendTimeout(DWORD dwTime/*=10000 默认10秒*/)
{
	m_dwSendTimeout = dwTime;
}

void CClientSocket::SetConnectTimeout(DWORD dwTime/*=10000 默认10秒*/)
{
	m_dwConnectTimeout = dwTime;
	m_bBlock = FALSE ;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -