📄 clientthread.cpp
字号:
// ClientThread.cpp : implementation file
//
#include "stdafx.h"
#include "Chat.h"
#include "ClientThread.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CClientThread
IMPLEMENT_DYNCREATE(CClientThread, CWinThread)
CClientThread::CClientThread()
{
m_bAutoDelete = FALSE;
nErrorCode = CLIENT_ERROR_NOERROR;
m_bState = CLIENT_ORIGIN;
m_hFinalWnd = NULL;
}
CClientThread::CClientThread(CString szHost, UINT nPort, BOOL bUseProxy, HWND hWnd, HWND hFinalWnd)
{
m_bAutoDelete = FALSE;
m_szHost = szHost;
m_nPort = nPort;
m_hMainWnd = hWnd;
nErrorCode = CLIENT_ERROR_NOERROR;
m_bUseProxy = bUseProxy;
m_bState = CLIENT_ORIGIN;
m_hWaitEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
m_hFinalWnd = hFinalWnd;
}
CClientThread::~CClientThread()
{
m_bState = CLIENT_CLOSED;
}
BOOL CClientThread::InitInstance()
{
int nResult;
// TODO: perform and per-thread initialization here
//从窗口读入要连接的主机名称或者IP
//启动TCPSocket的CreateClient,开始连接
m_bState = CLIENT_CONNECTING;
nResult = m_cTCPSocket.CreateClient( m_szHost, m_nPort, m_bUseProxy, m_hMainWnd, m_hFinalWnd);
if( nResult == FALSE )
{
//创建立即失败
//发送退出消息
//带回错误码
nResult = m_cTCPSocket.GetLastError();
nErrorCode = CLIENT_ERROR_CREATE;
m_bState = CLIENT_QUITING;
PostMessage( m_hMainWnd, WM_THREAD_QUIT, FALSE, MAKELONG(nResult, FALSE) );
//等待原窗口调用KillThread退出
SetEvent( m_hWaitEvent );
return TRUE;
}
//开始等待TCPSocket发来的SOCKET_THREAD_CONNECT
//或者出错等消息
m_bState = CLIENT_WAITING;
PostMessage( m_hMainWnd, WM_THREAD_CONNECT, 0, 0 );
if( m_bUseProxy == FALSE )m_hMainWnd = m_hFinalWnd;
SetEvent( m_hWaitEvent );
return TRUE;
}
int CClientThread::ExitInstance()
{
// TODO: perform any per-thread cleanup here
return CWinThread::ExitInstance();
}
BEGIN_MESSAGE_MAP(CClientThread, CWinThread)
//{{AFX_MSG_MAP(CClientThread)
// NOTE - the ClassWizard will add and remove mapping macros here.
ON_THREAD_MESSAGE( SOCKET_THREAD_READ, OnSocketRead )
ON_THREAD_MESSAGE( SOCKET_THREAD_WRITE, OnSocketWrite )
ON_THREAD_MESSAGE( SOCKET_THREAD_CLOSE, OnSocketClose )
ON_THREAD_MESSAGE( WM_THREAD_DATA, OnThreadData )
ON_THREAD_MESSAGE( WM_THREAD_QUIT, OnThreadQuit)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CClientThread message handlers
void CClientThread::KillThread()
{
//已经关闭,基本不可能出现
if( m_bState == CLIENT_CLOSED ) return;
if( m_bState == CLIENT_CONNECTING )
{
//必须终止连接
m_cTCPSocket.Stop();
}
PostThreadMessage( WM_QUIT, 0, 0 );
WaitForSingleObject( m_hThread, INFINITE );
delete this;
}
int CClientThread::GetLastError()
{
return nErrorCode;
}
void CClientThread::OnSocketConnect()
{
if( m_bState == CLIENT_CONNECTING )
m_cTCPSocket.StopWait();
}
SOCKET CClientThread::GetSocket()
{
return m_cTCPSocket.GetSocket();
}
void CClientThread::OnSocketRead(WPARAM wParam, LPARAM lParam)
{
//收到正确的FD_READ消息
//从网络中读出数据,并想主窗口发送数据消息
int nResult;
LPBYTE lpTemp;
int nLen;
nResult = m_cTCPSocket.Receive();
if( nResult )
{
lpTemp = m_cTCPSocket.GetData( &nLen );
if( lpTemp )
PostMessage( m_hMainWnd, WM_THREAD_DATA, nLen, (LPARAM)lpTemp );
}
}
void CClientThread::OnSocketWrite(WPARAM wParam, LPARAM lParam)
{
//收到正确的FD_WRITE消息
////说明数据已经发出
m_cTCPSocket.EnableWrite();
}
void CClientThread::OnSocketClose(WPARAM wParam, LPARAM lParam)
{
//收到正确的FD_CLOSE消息
////说明socket已经关闭
///如果线程没有收到退出消息,而收到网络通知退出
////说明电路被中断,退出线程
if( m_bState == CLIENT_WAITING )
{
m_bState = CLIENT_QUITING;
PostMessage( m_hMainWnd, WM_THREAD_QUIT, FALSE, MAKELONG(SOCKET_ERROR_CLOSE, FALSE) );
}
////否则不处理
return;
}
void CClientThread::OnThreadData(WPARAM wParam, LPARAM lParam)
{
//wParam表示要发送的字节数
//lParam代表指针
int nResult;
//和Client线程保持同步
nResult = m_cTCPSocket.Send( (LPBYTE)lParam, wParam );
switch( nResult )
{
case SOCKET_ERROR_NOERROR:
::PostMessage( m_hMainWnd, SOCKET_THREAD_WRITE, TRUE, 0 );
break;
default:
::PostMessage( m_hMainWnd, SOCKET_THREAD_WRITE, FALSE, nResult );
break;
}
}
void CClientThread::OnThreadQuit(WPARAM wParam, LPARAM lParam)
{
//收到请求退出指令
//请求主窗口杀掉线程
PostMessage( m_hMainWnd, WM_THREAD_QUIT, FALSE, MAKELONG(0, FALSE ) );
}
CString CClientThread::GetHost()
{
return m_cTCPSocket.GetHost();
}
BOOL CClientThread::ChangeHandle()
{
m_hMainWnd = m_hFinalWnd;
return m_cTCPSocket.ChangeHandle();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -