📄 serverthread.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 + -