delphi 程序間通訊(管道通訊)
阿新 • • 發佈:2019-01-26
前段時間,因專案需求,需要用到管道通訊。感覺管道通訊就是一層窗戶紙,捅破了就好了。
需求是:客戶端(client),按鈕被觸發後,傳送指令給伺服器端(server),server接收到指令後進行相應的操作,並立馬返回資訊給client。對於client而言,只是主動呼叫了一個傳送和接收資訊的函式;對於server而言,需要有一個執行緒或者timer,一直在重新整理等待接收來自client端的資訊。與此同時,server被多次開啟和關閉,不影響兩者間的通訊。
話不多說,上程式碼:
server端:
1、server開啟時,建立管道
2、重新整理資訊FPipe := CreateNamedPipe(pipeName, PIPE_ACCESS_DUPLEX or FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE or PIPE_NOWAIT,PIPE_UNLIMITED_INSTANCES,255, 255, 100, nil); if FPipe < 0 then RaiseLastOsError;//Fpipe為全域性變數
3、最後server關閉時procedure TForm2.Timer1Timer(Sender: TObject); var Data: TBytes; nRead, nWrite: DWORD; Buffer: array[0..255] of Byte; Msg: string; begin FillChar(Buffer[0], 0, SizeOf(Buffer)); if ReadFile(FPipe, Buffer[0], 255, nRead, nil) then begin SetLength(Data, nRead); Move(Buffer[0], Data[0], nRead); Msg := TEncoding.UTF8.GetString(Data); mmLogs.Lines.Add(DateTimeToStr(Now) + ' client said: '); mmLogs.Lines.Add(Msg); Data := TEncoding.UTF8.GetBytes('hello: ' + Msg); if not WriteFile(FPipe, Data[0], Length(Data), nWrite, nil) then RaiseLastOsError; SetLength(Data, 0); end; end;
CloseHandle(FPipe);
Client端:
只需要提供一個函式,向server傳送訊息並接收返回的訊息
procedure TForm1.btnSendClick(Sender: TObject); var Data: TBytes; nSent, nRead: DWORD; Buffer: array[0..255] of Byte; Msg: string; begin if (mmMsg.Text = '') then raise Exception.Create('you can not send an empty msg! '); if WaitNamedPipe(pipeName,100) then begin FPipe := CreateFile(pipeName, GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); end; if (FPipe <= 0) then begin mmLogs.Lines.Add('server伺服器還沒有開啟'); RaiseLastOsError; exit; end; try Data := TEncoding.UTF8.GetBytes(mmMsg.Text); if not WriteFile(FPipe, Data[0], Length(Data), nSent, nil) then begin mmLogs.Lines.Add('server伺服器被關閉'); RaiseLastOsError; end; mmLogs.Lines.Add(DateTimeToStr(Now) + ' I said: '); mmLogs.Lines.Add(mmMsg.Text); FillChar(Buffer[0], 0, SizeOf(Buffer)); if not ReadFile(FPipe, Buffer[0], 255, nRead, nil) then RaiseLastOsError; SetLength(Data, nRead); Move(Buffer[0], Data[0], nRead); Msg := TEncoding.UTF8.GetString(Data); SetLength(Data, 0); mmLogs.Lines.Add(DateTimeToStr(Now) + ' they reply: '); mmLogs.Lines.Add(Msg); finally //CloseHandle(FPipe); end; end;