Ich muss mehrere Nachrichten zwischen einer systemeigenen Named Pipe und einer System.IO Named Pipe senden. Ich habe den Code für beide Enden dieser Kommunikation aus dem All-In-One Code Framework (IPC und RPC) erhalten.Senden Sie mehrere Nachrichten zwischen einer systemeigenen Named Pipe und einer System.IO Named Pipe
Server:
SafePipeHandle hNamedPipe = null;
try { SECURITY_ATTRIBUTES sa = null;
sa = CreateNativePipeSecurity();
// Create the named pipe.
hNamedPipe = NativeMethod.CreateNamedPipe(
Constants.FullPipeName, // The unique pipe name.
PipeOpenMode.PIPE_ACCESS_DUPLEX, // The pipe is duplex
PipeMode.PIPE_TYPE_MESSAGE | // Message type pipe
PipeMode.PIPE_READMODE_MESSAGE | // Message-read mode
PipeMode.PIPE_WAIT, // Blocking mode is on
PIPE_UNLIMITED_INSTANCES, // Max server instances
1024, // Output buffer size
1024, // Input buffer size
NMPWAIT_USE_DEFAULT_WAIT, // Time-out interval
sa // Pipe security attributes
);
if (hNamedPipe.IsInvalid)
{
throw new Win32Exception();
}
Console.WriteLine("The named pipe ({0}) is created.", Constants.FullPipeName);
// Wait for the client to connect.
Console.WriteLine("Waiting for the client's connection...");
if (!NativeMethod.ConnectNamedPipe(hNamedPipe, IntPtr.Zero))
{
if (Marshal.GetLastWin32Error() != ERROR_PIPE_CONNECTED)
{
throw new Win32Exception();
}
}
Console.WriteLine("Client is connected.");
//
// Receive a request from client.
//
string message;
bool finishRead = false;
do
{
byte[] bRequest = new byte[1024];
int cbRequest = bRequest.Length, cbRead;
finishRead = NativeMethod.ReadFile(
hNamedPipe, // Handle of the pipe
bRequest, // Buffer to receive data
cbRequest, // Size of buffer in bytes
out cbRead, // Number of bytes read
IntPtr.Zero // Not overlapped
);
if (!finishRead &&
Marshal.GetLastWin32Error() != ERROR_MORE_DATA)
{
throw new Win32Exception();
}
// Unicode-encode the received byte array and trim all the
// '\0' characters at the end.
message = Encoding.Unicode.GetString(bRequest).TrimEnd('\0');
Console.WriteLine("Receive {0} bytes from client: \"{1}\"", cbRead, message);
}
while (!finishRead); // Repeat loop if ERROR_MORE_DATA
//
// Send a response from server to client.
//
message = "Goodbye\0";
byte[] bResponse = Encoding.Unicode.GetBytes(message);
int cbResponse = bResponse.Length, cbWritten;
if (!NativeMethod.WriteFile(
hNamedPipe, // Handle of the pipe
bResponse, // Message to be written
cbResponse, // Number of bytes to write
out cbWritten, // Number of bytes written
IntPtr.Zero // Not overlapped
))
{
throw new Win32Exception();
}
Console.WriteLine("Send {0} bytes to client: \"{1}\"",
cbWritten, message.TrimEnd('\0'));
// Flush the pipe to allow the client to read the pipe's contents
// before disconnecting. Then disconnect the client's connection.
NativeMethod.FlushFileBuffers(hNamedPipe);
NativeMethod.DisconnectNamedPipe(hNamedPipe);
} catch (Exception ex) { Console.WriteLine ("Der Server führt den Fehler: {0}", ex.Message); } schließlich { if (hNamedPipe! = Null) { hNamedPipe.Close(); hNamedPipe = null; } }
Auftraggeber:
NamedPipeClientStream pipeClient = null;
try
{
// Try to open the named pipe identified by the pipe name.
pipeClient = new NamedPipeClientStream(
".", // The server name
Constants.PipeName, // The unique pipe name
PipeDirection.InOut, // The pipe is duplex
PipeOptions.None // No additional parameters
);
pipeClient.Connect(5000);
MessageBox.Show(
string.Format("The named pipe ({0}) is connected.", Constants.PipeName)
);
pipeClient.ReadMode = PipeTransmissionMode.Message;
//
// Send a request from client to server
//
for (int i = 0; i < 2; i++) {
string message = "hello my pipe dream\0";
byte[] bRequest = Encoding.Unicode.GetBytes(message);
int cbRequest = bRequest.Length;
pipeClient.Write(bRequest, 0, cbRequest);
MessageBox.Show(
string.Format("Send {0} bytes to server: \"{1}\"", cbRequest, message.TrimEnd('\0'))
);
}
//
// Receive a response from server.
//
do
{
byte[] bResponse = new byte[1024];
int cbResponse = bResponse.Length, cbRead;
cbRead = pipeClient.Read(bResponse, 0, cbResponse);
// Unicode-encode the received byte array and trim all the
// '\0' characters at the end.
string message = Encoding.Unicode.GetString(bResponse).TrimEnd('\0');
Console.WriteLine("Receive {0} bytes from server: \"{1}\"",
cbRead, message);
}
while (!pipeClient.IsMessageComplete);
}
catch (Exception ex)
{
new ErrorDialog(ex).ShowDialog();
}
finally
{
// Close the pipe.
if (pipeClient != null)
{
pipeClient.Close();
pipeClient = null;
}
}
}
Wie Sie oben im Abschnitt sehen von der for-Schleife in dem „eine Anforderung vom Client zum Server senden“, ich versuche, herauszufinden, wie mehrere senden Nachrichten an den Server. Ich sehe, dass der Server-Code durchläuft, bis die Methode NativeMethod.ReadFile() True zurückgibt. Mein Problem ist, dass es immer wahr zurückgibt, nachdem die erste Nachricht gelesen wurde, und die zweite Nachricht ignorierend. Also ist meine Frage speziell, was ich im Clientcode tun muss, damit diese Methode false zurückgibt, dann wird es gehen die zweite Nachricht.