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

📄 serverthread.cpp

📁 网络聊天工具原代码
💻 CPP
字号:
// ServerThread.cpp : implementation file
//

#include "stdafx.h"
#include "Chat.h"
#include "ServerThread.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CServerThread

IMPLEMENT_DYNCREATE(CServerThread, CWinThread)

CServerThread::CServerThread()
{
	m_bAutoDelete = FALSE;
	m_nPort = CHAT_PORT;
}

CServerThread::CServerThread( HWND hWnd, UINT nPort)
{
	m_bAutoDelete = FALSE;
	m_nPort = nPort;
	m_hMainWnd = hWnd;
	m_bState = SERVER_ORIGIN;
}

CServerThread::~CServerThread()
{
}

BOOL CServerThread::InitInstance()
{
	// TODO:  perform and per-thread initialization here
	//启动服务器
	int nResult;
	int nTemp;

	m_bState = SERVER_CREATE;
	m_bHaveClient = FALSE;

	nResult = m_cWaitTCPSocket.CreateServer( m_nPort, m_hMainWnd);
	if( nResult == FALSE )
	{
		//请求退出
		nResult = m_cWaitTCPSocket.GetLastError();

		// TRUE代表服务器
		// FALSE代表客户端		
		nTemp = MAKELONG(  nResult, TRUE );
		m_bState = SERVER_QUITING;
		PostMessage( m_hMainWnd, WM_THREAD_QUIT, FALSE, nTemp );
	}
	m_bState = SERVER_WAITING;
	
	return TRUE;
}

int CServerThread::ExitInstance()
{
	// TODO:  perform any per-thread cleanup here
	return CWinThread::ExitInstance();
}

BEGIN_MESSAGE_MAP(CServerThread, CWinThread)
	//{{AFX_MSG_MAP(CServerThread)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		ON_THREAD_MESSAGE( SOCKET_THREAD_CONNECT, OnThreadConnect )
		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 )
		ON_THREAD_MESSAGE( SOCKET_THREAD_SHUT, OnThreadShut)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CServerThread message handlers

void CServerThread::KillThread()
{
	PostThreadMessage( WM_QUIT, 0, 0 );
	WaitForSingleObject( m_hThread, INFINITE );
	delete this;
}

void CServerThread::OnThreadConnect(WPARAM wParam, LPARAM lParam)
{
	//调用m_cWaitTCPSocket的ACCEPT过程接收
	//并创建m_cTCPSocket
	int nResult;
	char temp[2];
	BOOL bIdle = (BOOL)wParam;

	CSingleLock single(&g_cMutexServer);
	single.Lock();


	if( m_bState != SERVER_WAITING ) return;


	if( bIdle )
	{

			m_bState = SERVER_ACCEPTING;
			nResult = m_cTCPSocket.CreateTransfer( &m_cWaitTCPSocket, m_hMainWnd );
			if( nResult == FALSE )
			{
					//出现接受错误
					m_bState = SERVER_WAITING;
					return;
			}
			m_bState = SERVER_WAITING;
			m_bHaveClient = TRUE;
			return;
	}
	else	//忙
	{
			m_bState = SERVER_ACCEPTING;
			nResult = m_cExceptTCPSocket.CreateTransfer( &m_cWaitTCPSocket, m_hMainWnd, FALSE );
			if( nResult == FALSE )
			{
				m_bState = SERVER_WAITING;
				return;
			}
			//发送忙数据,然后关闭
			temp[0] = CHAT_ACT_BUSY;
			m_cExceptTCPSocket.Send( (LPBYTE)temp, 1 );
			m_cExceptTCPSocket.Close();
			m_bState = SERVER_WAITING;
	}
	return;
}

SOCKET CServerThread::GetListenSocket()
{
	return m_cWaitTCPSocket.GetSocket();
}

SOCKET CServerThread::GetSocket()
{
	if( m_bHaveClient )return m_cTCPSocket.GetSocket();
	else return INVALID_SOCKET;
}

void CServerThread::OnSocketRead(WPARAM wParam, LPARAM lParam)
{
	//收到正确的FD_READ消息
	//从网络中读出数据,并想主窗口发送数据消息
	int nResult;
	LPBYTE lpTemp;
	int nLen;

	CSingleLock single(&g_cMutexServer);
	single.Lock();

	if( !m_bHaveClient ) return;

	nResult = m_cTCPSocket.Receive();
	if( nResult )
	{
		lpTemp = m_cTCPSocket.GetData( &nLen );
		if( lpTemp )
			PostMessage( m_hMainWnd, WM_THREAD_DATA, nLen, (LPARAM)lpTemp );
	}
}

void CServerThread::OnSocketWrite(WPARAM wParam, LPARAM lParam)
{
	//已经写出了
	CSingleLock single(&g_cMutexServer);
	single.Lock();

	m_cTCPSocket.EnableWrite();
}

void CServerThread::OnSocketClose(WPARAM wParam, LPARAM lParam)
{
	//收到正确的FD_CLOSE消息
	////说明socket已经关闭
	///如果线程没有收到退出消息,而收到网络通知退出
	////说明电路被中断,退出线程
	CSingleLock single(&g_cMutexServer);
	single.Lock();

	if( m_bHaveClient )
	{
		m_bHaveClient = FALSE;
		m_cTCPSocket.Close();
	}
	////否则不处理
	return;
}

void CServerThread::OnThreadShut(WPARAM wParam, LPARAM lParam)
{
	CSingleLock single(&g_cMutexServer);
	single.Lock();
	if( m_bHaveClient )
	{
		m_bHaveClient = FALSE;
		m_cTCPSocket.Close();
	}
}


void CServerThread::OnThreadData(WPARAM wParam, LPARAM lParam)
{
	int nResult;

	CSingleLock single(&g_cMutexServer);
	single.Lock();

	//收到窗口要传数据的命令

	if( m_bHaveClient )
	{
		//可以根据发送的情况决定如何处理
		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;
		}
	}
}

CString CServerThread::GetHost()
{
	if( m_bHaveClient )
	{
		return m_cTCPSocket.GetHost();
	}
	else return _T("");
}

void CServerThread::OnThreadQuit(WPARAM wParam, LPARAM lParam)
{
	CSingleLock single(&g_cMutexServer);
	single.Lock();

	if( !wParam )
	{
		//请求关闭连接
		if( m_bHaveClient )
		{
			m_cTCPSocket.Close();
			m_bHaveClient = FALSE;
		}
	}
	//请求退出服务线程
	//不可能到这里
}

⌨️ 快捷键说明

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