最近想剥离一下Ghost的IOCP网络模型,所以趁着晚上写了写笔记。边修改边笔记,结果完了入迷了就也不知道记笔记了。然后就是笔记看着有点乱,凑合看看。一开始是放到空间了。先从监听开始,看下远程管理,以下简称它。
看下代码:

void CSetting::OnApply() {    // TODO: Add your control notification handler code here    int prev_port = m_listen_port;    int prev_max_connections = m_max_connections;        UpdateData(TRUE);        if (prev_max_connections != m_max_connections)    {        if (m_connect_auto)            InterlockedExchange((LPLONG)&m_iocpServer->m_nMaxConnections, 8000);        else            InterlockedExchange((LPLONG)&m_iocpServer->m_nMaxConnections, m_max_connections);    }        if (prev_port != m_listen_port)        g_pFrame->Activate(m_listen_port, m_iocpServer->m_nMaxConnections);     ((CClientApp *)AfxGetApp())->m_IniFile.SetInt("Settings", "ListenPort", m_listen_port);    ((CClientApp *)AfxGetApp())->m_IniFile.SetInt("Settings", "MaxConnection", m_max_connections);    ((CClientApp *)AfxGetApp())->m_IniFile.SetInt("Settings", "MaxConnectionAuto", m_connect_auto);    SetDlgItemText(IDC_SHOWTIPS, "已保存设置");}

 

忽略掉写入配置文件的 这里调用 了Active的函数 追入代码:

void CMainFrame::Activate(UINT nPort, UINT nMaxConnections){    CString     str,strLogText;     if (m_iocpServer != NULL)    {        m_iocpServer->Shutdown();        delete m_iocpServer;     }    m_iocpServer = new CIOCPServer;     // 开启IPCP服务器    if (m_iocpServer->Initialize(NotifyProc, this, 100000, nPort))    {        CString IP;                char hostname[256];         gethostname(hostname, sizeof(hostname));        HOSTENT *host = gethostbyname(hostname);        if (host != NULL)            IP = inet_ntoa(*(IN_ADDR*)host->h_addr_list[0]);        else            IP = _T("127.0.0.1");         ShowWindow(SW_SHOW);        UpdateWindow();        CString web;        web.Format(_T("%s:%d"), IP,nPort);        m_wndStatusBar.SetPaneText(0, web);        strLogText.Format( "xxxxx  V1.2  监听端口: [%d]",  nPort );        g_pLogView->AddToLog(strLogText);    }    else    {        str.Format(_T("端口 %d 监听失败"), nPort);        AfxMessageBox(str);        ShowWindow(SW_SHOW);        UpdateWindow();        m_wndStatusBar.SetPaneText(0, str);        strLogText.Format( "xxxx   端口[%d]监听失败!",  nPort );        g_pLogView->AddToLog(strLogText);    }     m_wndStatusBar.SetPaneText(2, _T("Online: 0"));} 

 

先把代码复制到我们的MFC工程里,在做修改,把判断代码做一些简化

void CIOCPDlg::OnOK() {    // TODO: Add extra validation here    CString     str,strLogText;    if (m_iocpServer != NULL)    {        m_iocpServer->Shutdown();        delete m_iocpServer;    }    m_iocpServer = new CIOCPServer;    // 开启IPCP服务器    if (m_iocpServer->Initialize(NotifyProc, this, 100000, nPort))    {        CString IP;         char hostname[256];         gethostname(hostname, sizeof(hostname));        HOSTENT *host = gethostbyname(hostname);        if (host != NULL)            IP = inet_ntoa(*(IN_ADDR*)host->h_addr_list[0]);        else            IP = _T("127.0.0.1");        CString web;        web.Format(_T("%s:%d"), IP,nPort);        m_wndStatusBar.SetPaneText(0, web);        strLogText.Format( "开始监听端口: [%d]",  nPort );        AfxMessageBox(web);    }    else    {        str.Format(_T("端口 %d 监听失败"), nPort);        AfxMessageBox(str);    }}

 

 再看下这个m_iocpServer定义。在这之前 如果你清理过工程  你需要重新编译一下才可以看到

CIOCPServer *m_iocpServer = NULL;
 我们新建一个类先。然后替换掉CPP和头文件,另外编译,补全一下头文件。这里还需要创建一个CpuUsage类
再搞定以后编译出错,提示

 Deleting intermediate files and output files for project ‘IOCP测试 – Win32 Release’.

——————–Configuration: IOCP测试 – Win32 Release——————–
Compiling resources…
Compiling…
StdAfx.cpp
Compiling…
IOCP测试.cpp
IOCP测试Dlg.cpp
C:\Users\Administrator\Desktop\vc\MyProjects\IOCP测试\IOCP测试Dlg.cpp(183) : error C2065: ‘NotifyProc’ : undeclared identifier
C:\Users\Administrator\Desktop\vc\MyProjects\IOCP测试\IOCP测试Dlg.cpp(183) : error C2065: ‘nPort’ : undeclared identifier
C:\Users\Administrator\Desktop\vc\MyProjects\IOCP测试\IOCP测试Dlg.cpp(195) : error C2065: ‘m_wndStatusBar’ : undeclared identifier
C:\Users\Administrator\Desktop\vc\MyProjects\IOCP测试\IOCP测试Dlg.cpp(195) : error C2228: left of ‘.SetPaneText’ must have class/struct/union type
IOCPServer.cpp
C:\Users\Administrator\Desktop\vc\MyProjects\IOCP测试\IOCPServer.cpp(7) : fatal error C1083: Cannot open include file: ‘../MainFrm.h’: No such file or directory
Buffer.cpp
Generating Code…
执行 cl.exe 时出错.
IOCP测试.exe – 1 error(s), 0 warning(s)
这个时候我们继续修改。这里提示的都是一些没有定义的错误。很简单,我们继续做一些简化就可以了。
首先是第一个错误,我们看下这个Notify  这里是一个回调函数 我们定义一下

void CALLBACK CIOCPDlg::NotifyProc(){ }

 

 暂时是这样,因为我们还需要添加一个类,这里先暂时简化一下 另外 在前面的判断简化出了一点问题  有一段是要去掉的 所以更新后是

void CIOCPDlg::OnOK() {    // TODO: Add extra validation here    CString     str,strLogText;    if (m_iocpServer != NULL)    {        m_iocpServer->Shutdown();        delete m_iocpServer;    }    m_iocpServer = new CIOCPServer;    // 开启IPCP服务器    if (m_iocpServer->Initialize(NotifyProc, this, 100000, nPort))    {        CString IP;         char hostname[256];         gethostname(hostname, sizeof(hostname));        HOSTENT *host = gethostbyname(hostname);        if (host != NULL)            IP = inet_ntoa(*(IN_ADDR*)host->h_addr_list[0]);        else            IP = _T("127.0.0.1");        strLogText.Format( "开始监听端口: [%d]",  nPort );        AfxMessageBox(strLogText);    }    else    {        str.Format(_T("端口 %d 监听失败"), nPort);        AfxMessageBox(str);    }} 

 

紧接着就是修改IOCP  其实这一步做了花了很多时间,直接贴一下代码吧:

bool CIOCPServer::Initialize(NOTIFYPROC pNotifyProc, CIocp_testDlg* pFrame, int nMaxConnections, int nPort){    m_pNotifyProc   = pNotifyProc;    m_pFrame        =  pFrame;    m_nMaxConnections = nMaxConnections;    m_socListen = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);      if (m_socListen == INVALID_SOCKET)

另外就是在iocp.h头文件里做一下修改

class  CIocp_testDlg; class CIOCPServer{public:    void DisconnectAll();    CIOCPServer();    virtual ~CIOCPServer();     NOTIFYPROC                  m_pNotifyProc;    CIocp_testDlg*                  m_pFrame;        bool Initialize(NOTIFYPROC pNotifyProc, CIocp_testDlg* pFrame,  int nMaxConnections, int nPort);     static unsigned __stdcall ListenThreadProc(LPVOID lpVoid);    static unsigned __stdcall ThreadPoolFunc(LPVOID WorkContext); 

然后就大致可以了,代码有点粗糙,完成一小部分 ,可以再优化一下的。最后就是上效果图了