命名管道的使用

这篇博客详细介绍了如何在Delphi中通过创建管道实现服务器与客户端的进程间通信。首先,服务器端创建管道并启动子进程,然后连接管道等待客户端连接。客户端则连接到服务器端的管道并发送数据。整个过程涉及CreatePipe、CreateProcessA、ConnectNamedPipe、ReadFile和WriteFile等函数的使用,展示了Windows API在进程通信中的应用。
摘要由CSDN通过智能技术生成

 

服务器断代码


procedure TForm1.btnProcessCreateClick(Sender: TObject);
var
  start: TStartupInfoA;
begin
  //1:创建管道
  CreatePipe;

  ZeroMemory(@Start,Sizeof(Start));
  start.cb          := SizeOf(start);
  start.hStdOutput  := 0;
  start.hStdInput   := 0;
  start.dwFlags     := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
  start.wShowWindow := SW_NORMAL;          //要显示子线程的窗体

  //2:创建子程序
  if CreateProcessA(nil,                  //不能使用CreateProcess    CreateProcess调用的是CreateProcessW WideChar类型
     'Client.exe 10.1.1.198',             //如果要给进程传参数,建议将进程和参数都通过第二次参数传递进去
     nil,
     nil,
     False,
     NORMAL_PRIORITY_CLASS,
     nil,
     nil,
     start,
     processInfo) = False then
  begin
    ShowMessage('线程创建失败');
  end;

  //3:连接管道
  ConnectPipe;
end;

procedure TForm1.ConnectPipe;
var
  handle: THandle;
  ovlap: TOverlapped;
begin
  //3:连接管道
  //创建管道的人工重置事件
  handle := CreateEvent(nil, True, False, nil);                 //第二个参数需要为True
  if handle = INVALID_HANDLE_VALUE then
  begin
    ShowMessage('Create Event Failed');
  end;
  ZeroMemory(@ovlap, sizeof(ovlap));
  ovlap.hEvent := handle;

  //等待客户端的连接请求
  ConnectNamedPipe(FPipeHanle, @ovlap);                          //第二个参数不能为空,必须指向一个TOverlapped
  if WaitForSingleObject(handle, INFINITE) = WAIT_FAILED then
  begin
    ShowMessage('ConnectNamedPipe failed');
    Exit;
  end;
end;

procedure TForm1.CreatePipe;
begin
  if FPipeHanle <> INVALID_HANDLE_VALUE then
  begin
    CloseHandle(FPipeHanle);
  end;

  //1:创建管道
  FPipeHanle := CreateNamedPipe('\\.\Pipe\UpgradeBcs',                            //管道名必须为 \\.\Pipe\pipename
                                 PIPE_ACCESS_DUPLEX or FILE_FLAG_OVERLAPPED,      //FILE_FLAG_OVERLAPPED  重叠操作, 读写不阻塞
                                 0, 1, 1024, 1024, 0, nil);
  if FPipeHanle = INVALID_HANDLE_VALUE then
  begin
    ShowMessage(format('CreateNamePipe failed with error %d',[GetLastError()]));
    Exit;
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  CloseHandle(ProcessInfo.hProcess);
  CloseHandle(ProcessInfo.hThread);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FPipeHanle := INVALID_HANDLE_VALUE;
end;

procedure TForm1.tmr1Timer(Sender: TObject);
var
  buf: array [0..99] of Byte;
  size: Cardinal;
begin
  if FPipeHanle <> INVALID_HANDLE_VALUE then
    Exit;
  if ReadFile(FPipeHanle, buf, 4, size, nil) = True then
  begin
    scrlbr1.Position := buf[0];
  end;
end;

 

客户端代码,客户端用控制台来显示

 SetConsoleTitle('客户端窗口');

  Writeln(ParamStr(1));                                            //打印传给此进程的参数

  //1:连接管道
  if WaitNamedPipe('\\.\Pipe\UpgradeBcs', 10000) = False then      //注意管道名要和服务器端一致
  begin
    Writeln('wait pipe failed');
    Exit;
  end;
  //2:打开命名管道
  PipeHandle := CreateFile('\\.\Pipe\UpgradeBcs', GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if PipeHandle = INVALID_HANDLE_VALUE then
  begin
    Writeln('Open pipe failed');
    Exit;
  end;

  WriteLn('Open pipe successful');

  while (SendNum < 100) do
  begin
    WriteLn(IntToStr(SendNum));
    //3:往管道里面写数据
    WriteFile(PipeHandle, SendNum, 4, WrSize, nil);
    Inc(SendNum);
    Sleep(10);
  end;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值