📄 tcpclient_ce.cpp
字号:
// TCPClient_CE.cpp: implementation of the CTCPClient_CE class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SendData.h"
#include "TCPClient_CE.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CTCPClient_CE::CTCPClient_CE()
{
//初始化socket环境
WSADATA wsd;
WSAStartup(MAKEWORD(1,1),&wsd);
//创建线程退出事件句柄
m_exitThreadEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
}
CTCPClient_CE::~CTCPClient_CE()
{
//释放socket资源
WSACleanup();
//关闭线程退出事件句柄
CloseHandle(m_exitThreadEvent);
}
DWORD CTCPClient_CE::SocketThreadFunc(LPVOID lparam)
{
CTCPClient_CE *pSocket;
//得到CTCPClient_CE 实例指针
pSocket=(CTCPClient_CE*)lparam;
//定义读事件集合
fd_set fdRead;
int ret;
//定义事件等待时间
TIMEVAL aTime;
aTime.tv_sec=1;
aTime.tv_usec=0;
while (TRUE)
{
//收到退出事件,结束线程
if (WaitForSingleObject(pSocket->m_exitThreadEvent,0)==WAIT_OBJECT_0)
{
break;
}
//置fdRead 事件为空
FD_ZERO(&fdRead);
// 给客户端socket 设置读事件
FD_SET(pSocket->m_socket,&fdRead);
//调用select 函数,判断是否有读事件发生
ret=select(0,&fdRead,NULL,NULL,&aTime);
if(ret==SOCKET_ERROR)
{
//触发错误事件
pSocket->OnError(pSocket->m_pOwnerWnd,1);
//触发连接断开事件
pSocket->OnDisConnect(pSocket->m_pOwnerWnd);
//关闭客户端socket
closesocket(pSocket->m_socket);
break;
}
if(ret>0)
{
if(FD_ISSET(pSocket->m_socket,&fdRead))
{
//发生读事件
char recvBuf[1024];
int recvLen;
ZeroMemory(recvBuf,1024);
//接收数据
recvLen=recv(pSocket->m_socket,recvBuf,1024,0);
if(recvLen==SOCKET_ERROR)
{
int iError=WSAGetLastError();
//触发Socket错误事件
pSocket->OnError(pSocket->m_pOwnerWnd,iError);
//触发与服务器断开事件
pSocket->OnDisConnect(pSocket->m_pOwnerWnd);
//关闭客户端 socket
closesocket(pSocket->m_socket);
break;
}
else if(recvLen==0)
{
//触发与服务器端断开事件
pSocket->OnDisConnect(pSocket->m_pOwnerWnd);
//关闭客户端socket
closesocket(pSocket->m_socket);
break;
}
else
{
//触发数据接收事件
pSocket->OnRead(pSocket->m_pOwnerWnd,recvBuf,recvLen);
}
}
}
}
return 0;
}
bool CTCPClient_CE::Open(CWnd *pWnd)
{
//复位线程退出事件
ResetEvent(m_exitThreadEvent);
//存储父窗口句柄
m_pOwnerWnd = pWnd;
//创建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 == NULL)
{
closesocket(m_socket);
return FALSE;
}
return TRUE;
}
bool CTCPClient_CE::Close()
{
//发送通讯线程结束事件
SetEvent(m_exitThreadEvent);
Sleep(1000);
//关闭Socket,释放资源
int err = closesocket(m_socket);
if (err == SOCKET_ERROR)
{
return FALSE;
}
return TRUE;
}
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));
if (err == SOCKET_ERROR)
{
return FALSE;
}
//设置通讯模式为异步模式
DWORD ul= 1;
ioctlsocket(m_socket,FIONBIO,&ul);
return TRUE;
}
bool CTCPClient_CE::SendData(const char *buf, int len)
{
int nBytes = 0;
int nSendBytes=0;
while (nSendBytes < len)
{
nBytes = send(m_socket,buf+nSendBytes,len-nSendBytes,0);
if (nBytes==SOCKET_ERROR )
{
int iErrorCode = WSAGetLastError();
//触发socket的Error事件
OnError(m_pOwnerWnd,iErrorCode);
//触发与服务器端断开连接事件
OnDisConnect(m_pOwnerWnd);
//关闭socket
Close();
return FALSE;
}
nSendBytes = nSendBytes + nBytes;
if (nSendBytes < len)
{
Sleep(1000);
}
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -