远程主机流程图:
客户机流程图:
CGh0stApp theApp; 唯一的实例在初始化中调用了主框架的 Activate 函数:
BOOL CGh0stApp::InitInstance()
{
((CMainFrame*) m_pMainWnd)->Activate(nPort, nMaxConnection);
}
Activate 函数构造了一个 CIOCPServer 对象,然后调用 Initialize 函数初始化:
void CMainFrame::Activate(UINT nPort, UINT nMaxConnections)
{
m_iocpServer = new CIOCPServer;
m_iocpServer->Initialize(NotifyProc, this, 100000, nPort)
}
Initialize 注册了一个回调函数 m_pNotifyProc ,创建了一个监听套接字,一个监听线程 ListenThreadProc ,然后初始化 IOCP 服务端
bool CIOCPServer::Initialize(NOTIFYPROC pNotifyProc, CMainFrame* pFrame, int nMaxConnections, int nPort)
{
m_pNotifyProc = pNotifyProc;
m_socListen = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
nRet = bind(m_socListen, (LPSOCKADDR)&saServer, sizeof(struct sockaddr));
nRet = listen(m_socListen, SOMAXCONN);
m_hThread =(HANDLE)_beginthreadex(NULL,0,ListenThreadProc,(void*) this,0,&dwThreadId);
InitializeIOCP();
}
IOCP 注册的回调函数 NotifyProc ,
收到 NC_CLIENT_DISCONNECT 就从客户列表视图移除,
收到 NC_RECEIVE 调用 ProcessReceive 函数,
收到 NC_RECEIVE_COMPLETE 调用 ProcessReceiveComplete 函数
void CALLBACK CMainFrame::NotifyProc(LPVOID lpParam, ClientContext *pContext, UINT nCode)
{
switch (nCode)
{
case NC_CLIENT_CONNECT:
break;
case NC_CLIENT_DISCONNECT:
g_pConnectView->PostMessage(WM_REMOVEFROMLIST, 0, (LPARAM)pContext);
break;
case NC_TRANSMIT:
break;
case NC_RECEIVE:
ProcessReceive(pContext);
break;
case NC_RECEIVE_COMPLETE:
ProcessReceiveComplete(pContext);
break;
}
}
void CMainFrame::ProcessReceive(ClientContext *pContext)
{
if (pContext == NULL)
return;
// 如果管理对话框打开,交给相应的对话框处理
CDialog *dlg = (CDialog *)pContext->m_Dialog[1];
// 交给窗口处理
if (pContext->m_Dialog[0] > 0)
{
switch (pContext->m_Dialog[0])
{
case SCREENSPY_DLG:
((CScreenSpyDlg *)dlg)->OnReceive();
break;
default:
break;
}
return;
}
}
void CMainFrame::ProcessReceiveComplete(ClientContext *pContext)
{
if (pContext == NULL)
return;
// 如果管理对话框打开,交给相应的对话框处理
CDialog *dlg = (CDialog *)pContext->m_Dialog[1];
// 交给窗口处理
if (pContext->m_Dialog[0] > 0)
{
switch (pContext->m_Dialog[0])
{
case SCREENSPY_DLG:
((CScreenSpyDlg *)dlg)->OnReceiveComplete();
break;
default:
break;
}
return;
}
switch (pContext->m_DeCompressionBuffer.GetBuffer(0)[0])
{
case TOKEN_AUTH: // 要求验证
m_iocpServer->Send(pContext, (PBYTE)m_PassWord.GetBuffer(0), m_PassWord.GetLength() + 1);
break;
case TOKEN_HEARTBEAT: // 回复心跳包
{
BYTE bToken = COMMAND_REPLAY_HEARTBEAT;
m_iocpServer->Send(pContext, (LPBYTE)&bToken, sizeof(bToken));
}
break;
case TOKEN_LOGIN: // 上线包
{
if (m_iocpServer->m_nMaxConnections <= g_pConnectView->GetListCtrl().GetItemCount())
{
closesocket(pContext->m_Socket);