命名管道
2018-2-20
一、引子
由于ARINC 429板卡一般是独占的,资源颗粒太大,因此需要增加一层,分层实现,以实现资源合理分配。
方案1:
服务端采基于控制台方式,正常情况下控制台隐藏,调试模式下控制台显示,收到命令退出
方案2:
采用服务+监控+配置+客户端,配置可以采用cpl,服务基于服务
方案3:
服务端(包含服务、监控、配置等,基于MFC,最小化到托盘)+客户端
方案3最通用,也最简单
客户端和服务端之间通信
方法1:
通过SOCKET方法
方法2:
基于命名管道
各有利弊,难以权衡,当然鱼和熊掌可兼得嘛,前提是都得很熟悉,但命名管道我不熟啊,幸好有春节期间还算有点时间。
二、命名管道
这玩意资料一搜一堆,虽然我没达到有陈寅恪先生“四不讲”境界,但百度到一堆的我就不再列出了。
其实只需CreateNamedPipe,CreateFile,WriteFile、PeekNamedPipe、ReadFile这几个函数就能不阻塞地读写了,不需要那么复杂,Simplest andBest
读数据嘛,读完了就不读了,写数据嘛,写满了就不写了,即便错过了一些东西,也没啥大不了的。
#include "stdafx.h"
#include "namePipe.h"
#define PIPE_BUF_LEN 128
//创建命名管道(Server)
HANDLE createNP(char* name)
{
returnCreateNamedPipe( name, //pointer to pipe name
PIPE_ACCESS_DUPLEX| FILE_FLAG_OVERLAPPED | WRITE_DAC, //pipe open mode 双向 重叠(异步)
PIPE_TYPE_BYTE| PIPE_READMODE_BYTE | PIPE_NOWAIT,// pipe-specific modes
PIPE_UNLIMITED_INSTANCES, //maximum number of instances
PIPE_BUF_LEN, //output buffer size, in bytes
PIPE_BUF_LEN, //input buffer size, in bytes
100, //time-out time, in milliseconds
NULL); //pointer to security attributes
}
//打开命名管道(Client)
HANDLE openNP(char* name)
{
returnCreateFile( name, //pointer to name of the file
GENERIC_READ|GENERIC_WRITE, //access (read-write) mode
0, //share mode
NULL, //pointer to security attributes
OPEN_EXISTING, //how to create
FILE_FLAG_OVERLAPPED, //file attributes
NULL); //handle to file with attributes to copy
}
//读命名管道
DWORD readNP(HANDLE hNP, char* buf)
{
DWORD dwRead = NULL;
if(PeekNamedPipe(hNP,buf,PIPE_BUF_LEN,&dwRead,0,0))
if(dwRead)
ReadFile(hNP,buf, dwRead, &dwRead, NULL);
returndwRead;
}
//写命名管道
DWORD writeNP(HANDLE hNP, char* buf)
{
DWORDdwWrite = NULL;
WriteFile(hNP,buf, strlen(buf), &dwWrite, NULL);
return dwWrite;
}
三、测试
为简单起见,VC6
MFC核心代码如下:
HANDLE hArinc429;
void CServer429Dlg::OnBtnTx()
{
CString str;
GetDlgItemText(IDC_ED_TX, str);
writeNP(hArinc429,(LPSTR)(LPCSTR)str);
}
void CServer429Dlg::OnBtnRx()
{
char str[1024];
ZeroMemory(str,sizeof(str));
if(readNP(hArinc429,str))
SetDlgItemText(IDC_ED_RX, str);
else
SetDlgItemText(IDC_ED_RX, "");
}
void CServer429Dlg::OnBtnCreate()
{
hArinc429 = createNP("\\\\.\\pipe\\arinc429");
}
void CServer429Dlg::OnBtnOpen()
{
hArinc429 = openNP("\\\\.\\pipe\\arinc429");
}
Demo就一个程序,运行两次,上边的是Server,下面的是Client
Server是Create,Client是Open
各种组合地收发都正常,就这样吧。