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

📄 tcpclient_ce.cpp

📁 Windows CE下的客户端TCP/IP程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			pClient->m_nTimeout++; // 对超时的情况进行累加,超过MAX_TIMEOUT次,则表示链路已经无效
			if (pClient->m_nTimeout >= MAX_TIMEOUT)
			{
				pClient->SelfClose();
				//	pClient->Close();

				msg.Format(_T("超时,断开服务器"));
				::PostMessage(pClient->m_hwnd,WM_USER_GPS_TCP,TCP_ERROR,(LPARAM)msg.GetBuffer(0));
				break;
			}
        }
    }// end while(TRUE) 
    
    
   OutputDebugString(_T("Quit SocketThreadFunc Function\n"));
   return 0;
}

/*--------------------------------------------------------------------
【函数介绍】: 分配缓冲池,打开客户端socket,并启动客户端线程
【出口参数】: (无)
【返回  值】: TRUE:打开成功;FALSE:打开失败
说明:该函数用在modTCP_init,是用户线程调用的,所以如果调用失败,应该自动删除对象
---------------------------------------------------------------------*/
bool CTCPClient_CE::Open()
{
    //分配缓冲池,其中发送缓冲设置为10个缓冲块
    if (!m_buffqueue.AllocateBuff(m_nbuffMax))
    {
        return false;
    }
    if (!m_sendQueue.AllocateBuff(10))
	{
		return false;
    }
    //复位线程退出事件
    ResetEvent(m_exitThreadEvent);
    //创建TCP套接字 
    m_socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if (m_socket == SOCKET_ERROR)
    {
        return FALSE;
    }
    //创建通讯线程
    m_tcpThreadHandle = CreateThread(NULL,0,SocketThreadFunc,this,0,NULL);
    if (m_tcpThreadHandle == INVALID_HANDLE_VALUE)
    {
        closesocket(m_socket);
        m_socket = INVALID_SOCKET;
        return FALSE;
    }
    return TRUE;
}


/*--------------------------------------------------------------------
【函数介绍】: 用于主线程关闭客户端socket线程
【入口参数】:  (无)
【出口参数】:  (无)
【返回  值】: TRUE:关闭成功;FALSE:关闭失败
---------------------------------------------------------------------*/
bool CTCPClient_CE::Close()
{
    //发送通讯线程结束事件
    SetEvent(m_exitThreadEvent); // 设置线程退出信号
	SetEvent(m_exitWriteEvent);
    

    //关闭Socket,释放资源
	OutputDebugString(_T("Begin closesocket\n"));
    if (m_socket!=INVALID_SOCKET) 
    {
		closesocket(m_socket);
		m_socket = INVALID_SOCKET;
    }

	OutputDebugString(_T("Begin Wait m_tcpThreadHandle\n"));
	DWORD dwRet = WaitForSingleObject(m_tcpThreadHandle,INFINITE);
	if (dwRet == WAIT_OBJECT_0)
	{
		CloseHandle(m_tcpThreadHandle);
		m_tcpThreadHandle = INVALID_HANDLE_VALUE;
	}

	OutputDebugString(_T("Begin Wait m_tcpWriteHandle\n"));
	dwRet =WaitForSingleObject(m_tcpWriteHandle,INFINITE);
	if (dwRet == WAIT_OBJECT_0)
	{
		CloseHandle(m_tcpWriteHandle);
		m_tcpWriteHandle = INVALID_HANDLE_VALUE;
	}

	OutputDebugString(_T("TCP OK\n"));
	
    return TRUE;
}


/*--------------------------------------------------------------------
【函数介绍】: 用于建立与TCP服务器连接
【入口参数】: (无)
【出口参数】: (无)
【返回  值】: TRUE:建立连接成功;FALSE:建立连接失败
---------------------------------------------------------------------*/
bool CTCPClient_CE::Connect()
{
    struct sockaddr_in addr;
    int err;
    
    addr.sin_family = AF_INET;
    addr.sin_port = htons(m_port);
    //此处要将双字节转换成单字节
    char ansiRemoteHost[255];
    ZeroMemory(ansiRemoteHost,255);
    WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,m_remoteHost,wcslen(m_remoteHost)
        ,ansiRemoteHost,wcslen(m_remoteHost),NULL,NULL);
    
    addr.sin_addr.s_addr=inet_addr(ansiRemoteHost);
    //此时采用同步连接方式,connect直接返回成功或是失败
    err = connect(m_socket,(struct sockaddr *)&addr,sizeof(addr));
	CString		_err;

    if (err == 0) 
    {
		_err.Format(_T("connect %s:%d success\n"),m_remoteHost,m_port);
		OutputDebugString(_err);
		//设置通讯模式为异步模式
		DWORD ul= 1;
		ioctlsocket(m_socket,FIONBIO,&ul);
		return TRUE;
    }
	return FALSE;
}

/*--------------------------------------------------------------------
【函数介绍】: 向服务器端发送数据
【入口参数】: buf:待发送的数据
len:待发送的数据长度
【出口参数】: (无)
【返回  值】: TRUE:发送数据成功;FALSE:发送数据失败
---------------------------------------------------------------------*/
bool CTCPClient_CE::SendData(const char * buf , int len)
{
    int nBytes = 0;
    int nSendBytes=0;
    int	nCount = 0;
	DWORD	dwError;
    while (nSendBytes < len)
    {
        nBytes = send(m_socket,buf+nSendBytes,len-nSendBytes,0);
        if (nBytes==SOCKET_ERROR )
        {
			dwError = WSAGetLastError();
			if (dwError == WSAEWOULDBLOCK)
			{
				nBytes = 0;
				if (nCount++ > 5)
				{
					WSASetLastError(WSAETIMEDOUT);
					return FALSE;
				}
			}
			else
			{
				WSASetLastError(dwError);
				return FALSE;
			}
        }
        
        nSendBytes = nSendBytes + nBytes;
        
        if (nSendBytes < len)
        {
            Sleep(100);
        }
    } 
    return TRUE; 
}

/*
*	从缓冲池中取出一个缓冲块,存放数据
*	返回值:true  正确的存放了数据
*			false 缓冲池没有空闲空间
*/
bool CTCPClient_CE::AddBuff(const char *buf, int len)
{
    return m_buffqueue.AddData(buf,len);
}

/*
*	取出数据,并把数据原占用的缓冲块加入缓冲池内
*	返回值:true  成功取得数据
*			false 缓冲区内没有数据
*/
bool CTCPClient_CE::GetBuff(char *buf, int *plen)
{
    return m_buffqueue.GetData(buf,plen);
}

bool CTCPClient_CE::AddSendQueue(const char *buf, int len)
{
	return m_sendQueue.AddData(buf,len);
}

bool CTCPClient_CE::GetSendBuff(char *buf, int *plen)
{
    return m_sendQueue.GetData(buf,plen);
}

BOOL CTCPClient_CE::IsQueueEmpty(UINT nTag)
{
	if (nTag == SENDQUEUE)
		return m_sendQueue.IsEmpty();
	if (nTag == RECVQUEUE) 
		return m_buffqueue.IsEmpty();

	return TRUE;
}

/*
 *	CTCPClient_CE的生命周期伴随着SOCKET连接开始而开始,断开而结束。
 *	因此,m_bDead主要用来标识由于远程主机因素导致连接断开情况
 */
bool CTCPClient_CE::IsDead()
{
	return m_bDead;
}

void CTCPClient_CE::SelfClose()
{
	closesocket(m_socket);
	m_socket = INVALID_SOCKET;
	m_bDead = true;	
}


/*
 *	由SocketThreadFunc产生写线程
 */
bool CTCPClient_CE::BeginWriteThread()
{
	ResetEvent(m_exitWriteEvent);
	m_tcpWriteHandle = CreateThread(NULL,0,SocketWriteThread,this,0,NULL);
    if (m_tcpThreadHandle == INVALID_HANDLE_VALUE)
		return false;
	return true;
}

LPCTSTR CTCPClient_CE::GetErrorString()
{
	static	wchar_t	msg[128];
	DWORD	code = WSAGetLastError();
	
	switch(code)
	{
	case 10060:
		wcscpy(msg,_T("\n原因:连接基站服务器超时!"));
		break;
	case 10061:
		wcscpy(msg,_T("\n原因:基站服务器软件可能未启动!"));
		break;
	case 10065:
		wcscpy(msg,_T("\n原因:可能未打开GPRS!"));
	    break;
	case 10054:
		wcscpy(msg,_T("\n原因:连接被强制关闭!"));
	    break;
	default:
		wcscpy(msg,_T("\n原因:请检查或重试!"));
	    break;
	}

	return (LPCTSTR)msg;
}

⌨️ 快捷键说明

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