Hey,
ich versuche mich grade an wenig an Named Pipes. Jetzt möchte ich praktisch einen Pipe Server öffnen, der auf Clients wartet und Daten von den Clients lesen kann. Dies funktioniert soweit:
Delphi-Quellcode:
var
FSA: SECURITY_ATTRIBUTES;
FSD: SECURITY_DESCRIPTOR;
hPipe: THandle;
dwRead: DWord;
begin
InitializeSecurityDescriptor(@FSD, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(@FSD, true, nil, false);
FSA.lpSecurityDescriptor := @FSD;
FSA.nLength := SizeOf(SECURITY_ATTRIBUTES);
FSA.bInheritHandle := true;
hPipe := CreateNamedPipe(PChar('\\.\pipe\test'),
FILE_FLAG_FIRST_PIPE_INSTANCE or PIPE_ACCESS_DUPLEX or
FILE_FLAG_WRITE_THROUGH,
PIPE_WAIT or PIPE_TYPE_MESSAGE or PIPE_READMODE_MESSAGE,
PIPE_UNLIMITED_INSTANCES, 1024, 1024, 50, @FSA);
if (hPipe <> INVALID_HANDLE_VALUE) then
begin
ShowMessage('pipe server created');
ServerThread := TPipeServer.Create(true);
ServerThread.hPipe := hPipe;
ServerThread.Resume;
end else
begin
ShowMessage('pipe server already running');
end;
end;
procedure TPipeServer.Execute;
var
dwRead: DWord;
begin
while not terminated do
begin
if ConnectNamedPipe(hPipe, nil) {and (GetLastError = ERROR_PIPE_CONNECTED) }then
begin
if ReadFile(hPipe, Buffer[0], SizeOf(Buffer), dwRead, nil) then
begin
ShowMessage(String(Buffer[0]));
FlushFileBuffers(hPipe);
DisconnectNamedPipe(hPipe);
end;
end;
end;
end;
Schreiben funktioniert auf Clientseite so:
Delphi-Quellcode:
var
FSA: SECURITY_ATTRIBUTES;
FSD: SECURITY_DESCRIPTOR;
hPipe: THandle;
dwWritten: DWord;
S: AnsiString;
begin
InitializeSecurityDescriptor(@FSD, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(@FSD, true, nil, false);
FSA.lpSecurityDescriptor := @FSD;
FSA.nLength := SizeOf(SECURITY_ATTRIBUTES);
FSA.bInheritHandle := true;
hPipe:= CreateFile(PChar('\\.\pipe\test'),
GENERIC_READ or GENERIC_WRITE, 0, @FSA, OPEN_EXISTING, 0, 0);
if (hPipe <> INVALID_HANDLE_VALUE) then
begin
ShowMessage('pipe opened');
S := 'Hallo Pipe Server';
WriteFile(hPipe, S[1], Length(S), dwWritten, nil);
end else
begin
ShowMessage(SysErrorMessage(GetLastError));
end;
end;
Das Problem ist jetzt folgendes. Nach dem Schreiben der Daten, wird der Client disconnected (wegen DisconnectPipe()). Lasse ich DisconnectPipe() weg, erhalte ich beim nächsten CreateFile() ein GetLastError = Alle Pipe Instanzen sind ausgelastet.
Wie schaffe ich es jetzt aber, dass ich über den Server Daten an alle Pipes schicken kann? Gibt es irgendeine Funktion, die ähnlich wie ConnectPipe() im Server darauf wartet, dass beim Server Daten geschrieben werden?
Viele Grüße
Zacherl