名前付きパイプを使用して2つのアプリケーションが通信しています。名前付きパイプ:サーバー側がクライアントが切断されたことをどのように知ることができますか?
メインプログラムはクライアントプログラムを呼び出し、通信するパイプサーバーを作成します。クライアントプログラムはパイプクライアントを作成します。メインプログラムはクライアントプログラムに任意のメッセージを送信することができ、何らかの方法でクライアント側で処理する必要があります。クライアントプログラムが終了すると、メインプログラムにメッセージが送信され、サーバーパイプを閉じる必要があることを意味します。
PipeDirection.OutのあるサーバーとPipeDirection.Inのクライアントを使用して、最初の部分(サーバーからクライアントにメッセージを送信する)を実装する際に問題はありませんでした。しかし、サーバーとクライアントの両方がPipeDirection.InOut(クライアントからサーバーにメッセージを送信できるように)を持つようにコードを変更しようとすると、コードが機能しなくなりました。 writer.Flush(サーバー側)またはwriter.WriteByte(クライアント側)を実行すると、プログラムがハングします。現在ハングしている場所は[HANGS HERE]とマークされています。
Serverは、このように作成されます。
public static void CreatePipeServerStream()
{
var namedPipeServerStream = new NamedPipeServerStream("somename", PipeDirection.InOut);
namedPipeServerStream.WaitForConnection();
// This thread is wating for message from client
ThreadStart starter =() => WaitForSignalFromClient(namedPipeServerStream);
new Thread(starter).Start();
}
private static void WaitForSignalFromClient(NamedPipeServerStream namedPipeServerStream)
{
if (namedPipeServerStream.IsConnected)
{
namedPipeServerStream.ReadByte();
// we'll get here after something is read
// and if we got here, we should close the server pipe
// now I can get here only if I shut down the client program using Task manager
namedPipeServerStream.Close();
}
}
クライアントにメッセージを送信する手順をやっているこの(サーバが==アウトパイプの方向性を持っていたし、クライアントがパイプの方向== Inを持っていたときに動作するために使用):
クライアント側ではpublic static void SendMessageUsingPipe(NamedPipeServerStream namedPipeServerStream)
{
if (namedPipeServerStream.IsConnected)
{
var sw = new StreamWriter(namedPipeServerStream);
sw.WriteLine("smth");
// [HANGS HERE]
sw.Flush();
}
}
、このコードは、別のスレッドで実行されている:
private void WaitServerCommands()
{
_pipe = new NamedPipeClientStream(".", "somename", PipeDirection.InOut);
using (var rdr = new StreamReader(_pipe))
{
while (true)
{
if (!_pipe.IsConnected)
{
_pipe.Connect();
}
rdr.ReadLine();
// I don't care what was sent by server, I just need to know that something was sent
Invoke(_handleCommand);
}
}
}
サーバーにメッセージを送信するコード:
private void ClosePipes()
{
if (_pipe != null && _pipe.IsConnected)
{
// [HANGS HERE]
_pipe.WriteByte(113);
_pipe.WaitForPipeDrain();
_pipe.Close();
}
}
コードに問題がありますか?それとも、私は何か基本的なことを忘れていますか
実際の問題は、サーバー側でクライアントが切断されていることを知る必要があることです。多分それは他の方法で達成することができますか?
私のケースでは、クライアントがほぼ即座に接続するので、WaitForConnectionは実際にはOKでした。しかし、あなたが正しいです、問題は、私のサーバーがクライアントからsmthを読んでいて、クライアントが同じことをしていたことでした。サーバーはクライアントに何かを送ることができませんでした。私はクライアントからの入力を待つことができず、同じ時間にメッセージを送信することができないことに気づいていませんでした。 – Nat