欢迎光临
未来你我一起携手

Ghost远程管理IOCP模型剥离笔记 端口的监听

最近想剥离一下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);
 

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

未经允许不得转载:卧栏听雨 » Ghost远程管理IOCP模型剥离笔记
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址