以命名管道方式实现网络进程间通信的一个实例

 
Win32 API 集支持的命名管道 (named pipe) 是实现网络进程间通信的一种有效手段。命名管道的接口比较简单 , 在程序中实现比较方便 , 由其开发的应用程序也很容易使用 , 只要知道机器及管道的名称即可连接两台机器上的两个进程。
命名管道首先由一进程调用 CreateNamedPipe 函数创建 , 这一创建命名管道的进程称为 Server 进程 , 然后 Server 进程通过调用 ConnectNamedPipe 函数等待一客户相连。在管道的另一段 ,Client 进程用 CreateFile 函数或 CallNamedPipe 函数打开管道句柄 , 若无可用的管道实例 ,Client 进程可调用 WaitNamedPipe 函数等待。一旦连接成功 ,Client 进程和 Server 进程可调用函数 ReadFile WriteFile ReadFileEx WriteileEx 传输信息。
笔者在应用程序开发过程中 , 曾用命名管道方法做了实现网络两进程间通信的一个小例子。这一例子实现了网络两进程间文本的实时互编辑操作 , 即在任一台机器上对文本的修改可实时反映到另一台机器上 , 就好像这一修改是在另一台机器上进行的一样。下面就对这一实验程序作一介绍。
程序分两部分 :Server 部分和 Client 部分。文中只介绍与命名管道实现有关的内容。
Server 部分
#define BUFSIZE 1280
HANDLE hPipe;
管道句柄
BOOL FConnected;
int Success=0;
typedef struct Infor{DWORD Type;
char Text[BUFSIZE-64];}; 信息传输结构
struct infor Info; 包含编辑控制的对话框
BOOL FAR PASCAL _export PipeServerDlg(HWND hDlg UINT message,WPARAM wParam,LPARAM IParam)
{
UINT IdTimer,DWORD ret,dwMode;
switch(message)
{
case WM_INITDIALOG;
IdTimer = SetTimer(hDlg,IdTimer,50,(TIMERPROC)NULL); Server 创建命名管道
hPipe = CreateNamedPipe(".//pipe//buf", 管道名
PIPE_ACCESS_DUPLEX, 双向传输
PIPE_WAIT|PIPE_TYPE_MESSAGE, 阻塞模式 , 消息流管道
PIPE_UNLIMITED_INSTANCES,, 可以创建数目不限的管道实例
BUFSIZE,BUFSIZE,1000,NULL);
If (hPipe!=INVALID_HANDLE_VALUE)
{ 管道句柄有效
FConnected = ConnectNamedPipe(hPipe,NULL); 等待连接
If (FConected)
Succes=1; 连接成功
Else
{
CloseHandle(hipe);
Succes=0;
}
}
if (Succes==1)
{    若连接成功 , 将阻塞模式变为非阻塞模式 ; 设置读模式为消息模式
dwMode=PIPE_READMODE_MESSAGE|PIPE_NOWAIT;
SetNamedPipeHandleState(hPipe,&dwMode,NULL,NULL);
}
return(TRUE);
case WM_TIMER;
if (Succes==1)
{   若连接成功 , 定时读管道数据
Info.Type=-1; 设初始值
If (ReadFile(hPipe,(char*)&Info,sizeof(Infor),&ret,NULL)==TRUE)
{   读管道数据
if (Info.Type==-2)
{   收到对方结束对话框信号 , 与对方同时结束对话框
KillTimer(hDig,IdTimer); CloseHandle(hPipe); Succes=0;
EndDialog(hDlg,TRUE); return(TRUE);
}
if (Info.Type==1)
SetDlgItemText(hDlg,IDC_EDIT1,Info.Text);
根据对方的变化修改编辑控制内容
}
}
break;
case WM_COMMAND;
if (GET_WM_COMMAND_ID(wParam,lParam)==IDOK)
{   结束对话框
KillTimer(hDlg.IdTimer);
If (Succes==1)
{
Info.Type = -2; 置结束对话框信号
WriteFile(hPipe,(char*)&Info,sizeof(Infor),&ret,NULL); 写数据到管道
CloseHandle(hPipe);
}
Succes=0;
EndDialog(hDlg,TRUE);
return(TRUE);
}
if (Succes==1&& LOWORD(wParam)==IDC_EDIT1&& HIWORD(wParam)== EN_UPDATE)
{   得到已修改的编辑控制中的内容 , 并写入管道
GetDlgItemText(hDlg,IDC_EDIT1,(LPSTR)(Info.Text),BUFSIZE-64);
Info.Type=1; Info.Type=1: 修改
WriteFile(hPipe,(char*)&Info,sizeof(Infor),&ret,NULL);
}
break;
}
return(FALSE);
}
Client 部分
#define BUFSIZE 1280
HANDLE hPipe 管道句柄
BOOL FConnected;
int Succes=0,Flag=0;
 
信息传输结构
typedef struct Infor
{
DWORD Type;
char Text[BUFSIZE-64];
};
struct Infor Info;
包含编辑控制的对话框
BOOL FAR PASCAL __export PipeClientDlg(HWND hDlg,UINT message,WPARAM wParam, LPARAM lParam)
{
UINT IdTimer;
DWORD ret,dwMode;
switch(message)
{
case WM_INITDIALOG:
IdTimer=SetTimer(hDlg,IdTimer,50,(TIMERPROC)NULL);
return(TRUE);
case WM_TIMER;
if (Succes==0&&Flag==0)
{     若未打开管道句柄 , 定时作打开操作
Client 打开管道句柄
hPipe = CreateFile("ServerName//pipe//buf", 管道名 ,ServerName 为运行服务器进程的机器名称
GENERIC_READ|GENERIC_WRITE, / 写模式
0, 文件非共享
NULL,OPEN_EXISTING,0,NULL);
If (hPipe!=INVALID_HANDLE_VALUE)
{    句柄有效
Succes=1;
Flag=1;
}
else
{
Flag=1;
If (!WaitNamedPipe("ServerName//pipe//buf",20000) 等待
Flag=0;
Clse
Succes=1;
}
if (Succes==1)
{    若连接成功 , 将阻塞模式变为非阻塞模式 ; 设置读模式为消息模式
dwMode = PIPE_READMODE_MESSAGE | PIPE_NOWAIT;
SetNamedPipeHandleState(hPipe,&dwMode,NULL,NULL);
}
}
if(Succes==1)
{     若连接成功 , 定时读管道数据
Info.Type=-1; 设置初值
If (ReadFile(hPipe,(char*)&Info,sizeof(Infor),&ret,NULL)==TRUE)
{
if (Info1.Type==-2)
{    收到对方结束对话框信号 , 与对方同时结束对话框
KillTimer(hDlg,IdTimer);CloseHandle(hPipe);
Succes = 0;
Flag = 0;
EndDialog(hDlg,TRUE);
return(TRUE);
}
if (Info.Type==1)
SetDlgItemText(hDlg.IDC_EDIT1,Info.Text);
}
}
break;
case WM_COMMAND;
if (GET_WM_COMMAND_ID(wParam,1Param)==IDOK)
{    结束对话框
KillTimer(hDlg,IdTimer);
If (Succes==1)
{
Info.Type = -2;
WriteFile(hPipe,(char*)&Info,sizeof(Infor),&ret,NULL);
CloseHandle(hPipe);
}
Succes = 0;
Flag = 0;
EndDialog(hDlg,TRUE);
return(TRUE);
}
if(Succes==1&&LOWORD(wParam)==IDC_EDIT1&&HIWORD(wParam)==EN_UPDATE)
{
GetDlgItemText(hDlg,IDC_ENIT1,(LPSTR)(Info.Text),BUFSIZE-64);
Info.Type = 1;
WriteFile(hPipe,(char*)&Info,sizeof(Infor),&ret,NULL);
}
break;
}
return(FALSE);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值