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

📄 clientthread.cpp

📁 网络聊天工具原代码 VC源码(网络编程
💻 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 + -