《远控编程笔记》 第六天

 第十一课、加入Socket数据传输的内核

  2.4 加入端口监听功能  

1.分析gh0st监听端口的函数:

             Activate(UINT nPort, UINT nMaxConnections)

2.需要一个回调函数,用于分类处理一些功能消息

             NotifyProc

3.复制NotifyProc 代码 到我们的dlg类中, 去掉多余的代码

头文件声明:

protected:

static void CALLBACK NotifyProc(LPVOID lpParam, ClientContext *pContext, UINT nCode);//消息处理函数

源文件实现:

 void CALLBACK CVeryEvilDlg::NotifyProc(LPVOID lpParam, ClientContext *pContext, UINT nCode)

{

try

{

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);   //这里时完全接收 处理发送来的数据 跟进    ProcessReceiveComplete

break;

}

}catch(...){}

}        

4,在dlg头文件还应该包含: #include "include\IOCPServer.h"

5.同样复制Activate 函数到我们的工程中去

声明:

protected:

void Activate(UINT nPort, UINT nMaxConnections);                                     //激活监听端口函数

函数实现:

void CVeryEvilDlg::Activate(UINT nPort, UINT nMaxConnections)

{

CString str;

if (m_iocpServer != NULL)

{

m_iocpServer->Shutdown();

delete m_iocpServer;

}

m_iocpServer = new CIOCPServer;

     

////lang2.1_8

// 开启IPCP服务器 最大连接  端口     查看NotifyProc回调函数  函数定义

  if (m_iocpServer->Initialize(NotifyProc, this, 100000, nPort))

  {

char hostname[256]; 

gethostname(hostname, sizeof(hostname));

HOSTENT *host = gethostbyname(hostname);

if (host != NULL)

for ( int i=0; ; i++ )

str += inet_ntoa(*(IN_ADDR*)host->h_addr_list[i]);

if ( host->h_addr_list[i] + host->h_length >= host->h_name )

break;

str += "/";

}

}

   m_wndStatusBar.SetPaneText(0, str);

  str.Format("端口: %d", nPort);

  m_wndStatusBar.SetPaneText(2, str);

  }

  else

  {

  str.Format("端口%d绑定失败", nPort);

  m_wndStatusBar.SetPaneText(0, str);

  m_wndStatusBar.SetPaneText(2, "端口: 0");

  }

m_wndStatusBar.SetPaneText(3, "连接: 0");

}

函数修改部分:if (m_iocpServer->Initialize(NotifyProc, NULL, 100000, nPort))

应为这里我们用不上这个指针了,就由this改为NULL。

6,在dlg的cpp文件的首部(用户自定义数据去声明) :CIOCPServer *m_iocpServer = NULL;  //CIOCPServer类对象指针,方便以后直接操作

7,在dlg的OnInitDialog中合适的位置(在我们的测试函数Test()之前调用)调用激活监听端口函数

Activate(2000,9999);//开启端口监听

7.监听后添加日志消息,把gh0st原本在状态栏显示的绑定状态信息在日志控件输出显示

部分代码如下:

void CVeryEvilDlg::Activate(UINT nPort, UINT nMaxConnections)

{

     .......................................

/*

   m_wndStatusBar.SetPaneText(0, str);

  str.Format("端口: %d", nPort);

  m_wndStatusBar.SetPaneText(2, str);

*/

str.Format("监听端口: %d成功", nPort);

        ShowMessage(true,str);

  }

  else

  {

/*

  str.Format("端口%d绑定失败", nPort);

  m_wndStatusBar.SetPaneText(0, str);

  m_wndStatusBar.SetPaneText(2, "端口: 0");

*/

str.Format("监听端口: %d失败", nPort);

        ShowMessage(false,str);

  }

//m_wndStatusBar.SetPaneText(3, "连接: 0");

}

8.测试  netstat -an



第十二课、加入Socket数据传输的内核

2.5 ini 配置文件的读写

1.认识几个读写ini文件的 API

               BOOL WINAPI WritePrivateProfileString(     //在ini文件中写入指定字符

  __in          LPCTSTR lpAppName,                       //节的名字                     

  __in          LPCTSTR lpKeyName,                      //键值的名字

  __in          LPCTSTR lpString,                       //要写入的内容 如果为NULL  则删除该键

  __in          LPCTSTR lpFileName                      //ini 文件名

);

UINT WINAPI GetPrivateProfileInt(                     //从ini文件中读取指定字符

  __in          LPCTSTR lpAppName,                    //节名字

  __in          LPCTSTR lpKeyName,                     //键值

  __in          INT nDefault,                          //读取的内容

  __in          LPCTSTR lpFileName                      //ini文件名

);

2.gh0st工程中已经对ini文件的读写有了很好的封装,我们有了初步的认识之后,底层实现我们也有了初步了解,现在就可以使用封装好的类了。

3.复制gh0st工程下的iniFile.h和iniFile.cpp到我们的工程中并添加,注释掉inifile.cpp中的#include "gh0st.h"

4查看gh0st是怎样读写ini文件的,到CGh0stApp::InitInstance()

            源码中讲解

5.大家可能会奇怪 ini 文件名从何而来,我们来看一下这个类的构造函数CIniFile::CIniFile()

          源码中讲解

6.剩下还有好多封装好的功能,有兴趣大家自己研究吧

7.声明一个ini 文件处理的变量CIniFile m_IniFile;  这个变量不应该到处声明,最好只声明一次,因为构造函数中,有一个文件处理的过程,影响程序运行速度,

 这样最好在CVeryEvilApp类中声明,以后使用就可以这样调用:

                                                 ((CVeryEvilApp*)AfxGetApp())->m_IniFile

8.为CPCRemoteDlg 添加一个成员函数ListenPort  用于管理监听的代码,写入内容: 

/****************从ini读取配置文件并设置监听端口函数*****************************/

void CVeryEvilDlg::ListenPort(void)

{

int nPort = ((CVeryEvilApp*)AfxGetApp())->m_IniFile.GetInt("Settings", "ListenPort");         //读取ini 文件中的监听端口

int nMaxConnection = ((CVeryEvilApp*)AfxGetApp())->m_IniFile.GetInt("Settings", "MaxConnection");   //读取最大连接数

if (nPort == 0)

nPort = 80;

if (nMaxConnection == 0)

nMaxConnection = 10000;

Activate(nPort,nMaxConnection);             //开始监听

}

9.替换OnInitDialog()中  Activate 函数改为ListenPort。

10.处理崩溃

在IniFIle类的构造函数中

::GetModuleFileName(AfxGetInstanceHandle(), szAppName, sizeof(szAppName));

改为:

::GetModuleFileName(NULL, szAppName, sizeof(szAppName));

11.添加监听端口的设置

    (1)添加对话框IDD_DIALOG_SETTING

    (2)添加两个编辑框控件(监听端口,最大连接数)  IDC_EDIT_PORT  ,IDC_EDIT_MAX

    (3)添加控件关联UINT变量  m_nListernProt;

            m_nMax_Connect;

    (4)为话框添加一个关联类 CSettingDlg

    

         

    (5)为对话框的“确定”按钮添加按钮事件并写入代码:  

void CSettingDlg::OnBnClickedOk()

{

// TODO: 在此添加控件通知处理程序代码

UpdateData(TRUE);

((CVeryEvilApp *)AfxGetApp())->m_IniFile.SetInt("Settings", "ListenPort", m_nListernProt);      //向ini文件中写入值

((CVeryEvilApp *)AfxGetApp())->m_IniFile.SetInt("Settings", "MaxConnection", m_nMax_Connect);

MessageBox("设置成功,重启本程序后生效!");

CDialogEx::OnOK();

}

   (6)在我们的主界面Dlg类的cpp文件包含头文件 #include "SettingDlg.h"

   (7)在以前我们的参数设置函数内添加代码

void CVeryEvilDlg::OnMainSet()

{//设置

// TODO: 在此添加命令处理程序代码

   CSettingDlg SettingDlg;

   SettingDlg.DoModal();

}

12.测试


你可能感兴趣的:(《远控编程笔记》 第六天)