📄 sockclient.cpp
字号:
#include "StdAfx.h"
#include "sockclient.h"
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"winmm.lib")
CSockClient::CSockClient(void)
{
m_dwProtocol = SOCK_STREAM;
m_bRunState = true;
sprintf( m_strHostIP, "NULL" );
m_dwHostPort = 0;
m_hEvent[0] = CreateEvent(NULL,0,0,0);
m_hEvent[1] = CreateEvent(NULL,0,0,0);
}
CSockClient::~CSockClient(void)
{
m_bRunState = false;
CloseHandle( m_hEvent[ 0 ] );
CloseHandle( m_hEvent[ 1 ] );
Cleanup();
}
bool CSockClient::Initialize(void)
{
WSADATA wsaData;
//建立winsock
if( WSAStartup( 0x0202 , &wsaData ) )
{
DebugMsg( "WSAStartup失败!\n" );
return false;
}
//判断版本
if( wsaData.wVersion != 0x0202 )
{
DebugMsg( "系统不支持Winsock 2.0!\n" );
WSACleanup();
return false;
}
return true;
}
void CSockClient::Cleanup(void)
{
//清除socket
if( m_sSocket != INVALID_SOCKET )
closesocket( m_sSocket );
//清除winsock
WSACleanup();
}
bool CSockClient::Create(DWORD dwProtocol)
{
//设置连接协议
m_dwProtocol = dwProtocol;
//创建套接字
m_sSocket = socket(PF_INET, m_dwProtocol, 0);
if(m_sSocket == INVALID_SOCKET)
{
DebugMsg( "创建套接字错误\n!");
return false;
}
//设置套接字运行状态
m_bRunState = true;
return true;
}
bool CSockClient::Connect(const char* strIP, DWORD dwPort)
{
//创建client线程
DWORD dwThreadID;
m_hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)ClientThread, this, 0, &dwThreadID );
if( m_hThread == NULL )
{
DebugMsg("创建client线程错误\n");
return false;
}
if( !strIP )
{
DebugMsg( "没有指定目标地址!\n" );
return false;
}
sprintf( m_strHostIP, "%s", strIP );
m_dwHostPort = dwPort;
//绑定套接字
SOCKADDR_IN addr;
memset( &addr, 0, sizeof(addr) );
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr( m_strHostIP );
if( addr.sin_addr.s_addr == INADDR_NONE )
{
LPHOSTENT lphost = gethostbyname( m_strHostIP );
if( lphost != NULL )
{
addr.sin_addr.s_addr = ( ( LPIN_ADDR )lphost->h_addr )->s_addr;
}
else
{
DebugMsg("无法解析目标地址!\n");
WSASetLastError(WSAEINVAL);
return false;
}
}
addr.sin_port = htons( (unsigned short)m_dwHostPort );
//连接
if(connect(m_sSocket, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR)
{
if( WSAGetLastError() == WSAEWOULDBLOCK )
{
DebugMsg("连接目标失败\n");
return false;
}
}
//设置事件选择
if( WSAEventSelect(m_sSocket, m_hEvent[0],FD_CONNECT | FD_CLOSE) == SOCKET_ERROR )
{
DebugMsg("连接事件选择错误\n");
return false;
}
return true;
}
DWORD CSockClient::GetBufferLength(void)
{
DWORD dwBufferLenght;
if( ioctlsocket(m_sSocket,FIONREAD,&dwBufferLenght) != SOCKET_ERROR )
return dwBufferLenght;
return 0;
}
bool CSockClient::RecvTcp(LPVOID lpBuffer,DWORD dwBufferLenght,DWORD dwFlags )
{
//接收
if( recv( m_sSocket , (char*)lpBuffer , (int)dwBufferLenght , (int)dwFlags) == SOCKET_ERROR )
{
if( WSAGetLastError() != WSAEWOULDBLOCK )
return false;
}
return true;
}
bool CSockClient::SendTcp(LPVOID lpBuffer,DWORD dwBufferLenght,DWORD dwFlags )
{
//发送
if( send( m_sSocket , (char*)lpBuffer , (int)dwBufferLenght , (int)dwFlags) == SOCKET_ERROR )
{
if( WSAGetLastError() != WSAEWOULDBLOCK )
return false;
}
return true;
}
bool CSockClient::ClientThread(LPVOID lpParam)
{
CSockClient* pSocket = (CSockClient*)lpParam;
if(pSocket == NULL)
return false;
//进入事件枚举循环
while(1)
{
if(!pSocket->GetRunState())
{
DebugMsg("线程终于结束了\n");
return false;
}
//等等那些事件的设定了
if( WaitForMultipleObjects( 2 , pSocket->GetEvent() , false , 10 ) == 1 )
{
DebugMsg("客户端事件没响应\n");
return false;
}
WSANETWORKEVENTS events;
//开try
try
{
// 枚举网络事件
if(WSAEnumNetworkEvents(pSocket->GetSocket(),pSocket->GetEvent()[0],&events))
{
DebugMsg("客户端线程枚举网络事件错误\n");
return false;
}
if(events.lNetworkEvents != 0)
{
//当连接成功
if(events.lNetworkEvents == FD_CONNECT)
{
if( events.iErrorCode[FD_CONNECT_BIT] == 0)
{
if( WSAEventSelect(pSocket->GetSocket(),pSocket->GetEvent()[0], FD_WRITE|FD_READ|FD_CLOSE) == SOCKET_ERROR )
{
DebugMsg("不能在连接后选择事件\n");
return false;
}
}
pSocket->GetClientThread()(pSocket,FD_CONNECT,0,(DWORD)events.iErrorCode[FD_CONNECT_BIT]);
}
//当收到消息
if(events.lNetworkEvents == FD_READ)
{
pSocket->GetClientThread()(pSocket,FD_READ,pSocket->GetBufferLength(),(DWORD)events.iErrorCode[FD_READ_BIT]);
}
//当发送消息
if(events.lNetworkEvents == FD_WRITE)
{
pSocket->GetClientThread()(pSocket,FD_WRITE,0,(DWORD)events.iErrorCode[FD_WRITE_BIT]);
}
//当关闭套接字
if(events.lNetworkEvents == FD_CLOSE)
{
pSocket->SetRunState(false);
pSocket->GetClientThread()(pSocket,FD_CLOSE,0,(DWORD)events.iErrorCode[FD_CLOSE_BIT]);
}
}
else
{
// 检测数据缓冲中是否有数据存在
if(pSocket->GetBufferLength())
{
pSocket->GetClientThread()(pSocket,FD_READ,pSocket->GetBufferLength(),0);
}
}
}
catch(...)
{
static long oldtime = 0;
long newtime = timeGetTime();
if( newtime - oldtime >= 10000 )
{
oldtime = newtime;
DebugMsg("网络连接超时,网速也太慢了\n");
}
}
}
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -