//============ // string型(文字列)読み込みメソッド // ストリームからデーターを読み込む。なお、その読み込むデーター // は、string型(文字列)として読み込む。 // 第1引数: 受信電文のエンコードを入力指定(シフトJISコード時は、"shift_jis") // 戻り値: 取得データー(string型) // // エンコーディングを示すコードページ名(第2引数指定値) // シフトJIS: "shift_jis" // JIS: "iso-2022-jp" // 日本語EUC: "euc-jp" // Unicode (UTF-8): "utf-8" public string ReadString(string BeforeEncod) { // バイト型配列(バイナリー)読み込みメソッドを実行 // --- ストリームからデーターを取得する。ただし、下記メソッド // では、バイト型配列(バイナリー)として読み込む。 byte[] inBuffer = ReadBytes(); // 取得したデーターをバイト型配列からstring型に変換 // (バイト型配列 ---> ユニコードstring 変換) string data; StringBytesController.ChangeBinaryToUnicodeStr( inBuffer, BeforeEncod, out data); // 取得したデーター値(string型)を返却 return(data); }
//============ // 返信受信 // サーバーから来る返信電文を受信する(すなわち、サーバーへ要求 // していた処理結果を、本メソッドで取得します)。 // 第1引数: クライアントクラス(各スレッド間の情報伝達に使用) public void ReceiveReply(PipeClient client) { //------------ // サーバーから返信(処理結果)を受け取る。 //------------ // 非同期操作のステータスを表すオブジェクト。 IAsyncResult result; try { // 返信(受信電文)のヘッダーを取得する。 // かつ、その後の処理を行なうメソッドを指定。 result = client.pipeClient.BeginRead(client.HeaderBuffer, 0, client.HeaderBuffer.Length, null, null); } catch (InvalidOperationException) //disconnected/disposed { return; } //------------ // 非同期操作完了 //------------ // 非同期処理が完了するまで待つ。 result.AsyncWaitHandle.WaitOne(); int bytesRead; try { // 非同期読み取りを完了するまで待機する操作を終了します。 bytesRead = client.pipeClient.EndRead(result); } catch (System.IO.IOException) //closed { return; } // 以下の処理は、サーバーから来た返信を読み始めてから実行 // されます。正確には、返信電文のヘッダーを読み終えた直後 // に、以下の処理の実行が開始されます。 // (それまで待機中となり、実行が開始されない) //------------ // ヘッダーの復元 // --- ヘッダーは、既に読み込み済みなので、後はそれをInt32型に復元する。 //------------ // 取得したデーターをバイト型配列からint型に変換 Int32 len = BitConverter.ToInt32(client.HeaderBuffer, 0); //------------ // データー本体読み込み //------------ // データー本体用バイト型配列 // 後にデーター本体を、バイト型配列に格納する時に使う。 byte[] inBuffer = new byte[len]; try { // ストリームからデーター本体を読み込む。 client.pipeClient.Read(inBuffer, 0, len); } catch (System.ObjectDisposedException) // ストリームが破棄されている場合 { return; } // 取得したデーターをバイト型配列からstring型に変換 // (バイト型配列 ---> ユニコードstring 変換) string temp; // 取得文字を格納するオブジェクト StringBytesController.ChangeBinaryToUnicodeStr( inBuffer, "shift_jis", out temp); // パイプストリーム解法 client.pipeClient.Close(); client.pipeClient.Dispose(); client.pipeClient = null; // 電文受信時に起動させるメソッドを実行 OnReceiveCall(DateTime.Now, temp); }
//============ // 要求電文受信待機 // クライアントから要求電文(命令)を受信します。 // 第1引数: サーバークラス(各スレッド間の情報伝達に使用) void ReceiveOrder(PipeServer p_server) { // Int32型のデーターのサイズ(Int32型サイズ) Int32 Int_Size = sizeof(Int32); // ヘッダー // Int32型データー用バイト型配列 // 後にint型データーを、バイト型配列に格納する時に使う。 byte[] HeaderBuffer = new byte[Int_Size]; // 非同期操作のステータスを表すオブジェクト。 IAsyncResult result; try { // 要求用受信電文のヘッダーを取得する。 // かつ、その後の処理を行なうメソッドを指定。 result = p_server.pipeServer.BeginRead(HeaderBuffer, 0, HeaderBuffer.Length, null, null); } catch (InvalidOperationException) //disconnected/disposed { return; } //------------ // 非同期操作完了 //------------ // 非同期処理が完了するまで待つ。 result.AsyncWaitHandle.WaitOne(); int bytesRead; try { // 非同期読み取りを完了するまで待機する操作を終了します。 bytesRead = p_server.pipeServer.EndRead(result); } catch (System.IO.IOException) //closed { return; } // 以下の処理は、クライアントから来た要求電文を読み始めてから // 実行されます。正確には、要求電文のヘッダーを読み終えた直後 // に、以下の処理の実行が開始されます。 // (それまで待機中となり、実行が開始されない) //------------ // ヘッダーの復元 // --- ヘッダーは、既に読み込み済みなので、後はそれをInt32型に復元する。 //------------ // 取得したデーターをバイト型配列からint型に変換 Int32 len = BitConverter.ToInt32(HeaderBuffer, 0); //------------ // データー本体読み込み //------------ // データー本体用バイト型配列 // 後にデーター本体を、バイト型配列に格納する時に使う。 byte[] inBuffer = new byte[len]; // ストリームからデーター本体を読み込む。 p_server.pipeServer.Read(inBuffer, 0, len); // 取得したデーターをバイト型配列からstring型に変換 // (バイト型配列 ---> ユニコードstring 変換) string OrderMessage; // 取得文字を格納するオブジェクト StringBytesController.ChangeBinaryToUnicodeStr( inBuffer, "shift_jis", out OrderMessage); // 電文受信時に起動させるメソッドを実行 OnReceiveCall(DateTime.Now, OrderMessage); // 返信用電文作成 // クライアントに返す返信用電文を作成します。なお、今までの // 流れでは、 // ss.WriteString("返信内容", "shift_jis"); // で返信したいところです。しかし、マイクロソフトのホームペ // ージ(MSDNホームページ)を見ますと、返信はRunAsClient() // と言うメソッドで行なうようなので、下記コードもそのように // します。 // ストリームに対して、文字データーを読み書きするオブジェクトを生成 AccessStream ss = new AccessStream(p_server.pipeServer); // 返信用メッセージをストリームに書き込む。 ss.WriteString(SendData, "shift_jis"); // 名前付きパイプのクローズ p_server.pipeServer.Close(); p_server.pipeServer.Dispose(); p_server.pipeServer = null; // 返信送信完了時に起動させるメソッドを実行 OnFinishTransmission(DateTime.Now); }
//============ // 接続通知受信メソッド // サーバーへ接続すると、無事に接続されたことを知らせる通知用電文が、 // サーバーから送られて来る仕様にしてあります。その通知を本メソッド // で受信します。 // 第1引数: クライアントクラス(各スレッド間の情報伝達に使用) private void ReceiveConnectionNotice(PipeClient client) { // 非同期操作のステータスを表すオブジェクト。 IAsyncResult result; try { // 接続通知用受信電文のヘッダーを取得する。 // かつ、その後の処理を行なうメソッドを指定。 result = client.pipeClient.BeginRead(client.HeaderBuffer, 0, client.HeaderBuffer.Length, null, null); } catch (InvalidOperationException) //disconnected/disposed { return; } //------------ // 非同期操作完了 //------------ // 非同期処理が完了するまで待つ。 result.AsyncWaitHandle.WaitOne(); int bytesRead; try { // 非同期読み取りを完了するまで待機する操作を終了します。 bytesRead = client.pipeClient.EndRead(result); } catch (System.IO.IOException) //closed { return; } // 以下の処理は、サーバーから来た接続通知を読み始めてから実行 // されます。正確には、接続通知電文のヘッダーを読み終えた直後 // に、以下の処理の実行が開始されます。 // (それまで待機中となり、実行が開始されない) //------------ // ヘッダーの復元 // --- ヘッダーは、既に読み込み済みなので、後はそれをInt32型に復元する。 //------------ // 取得したデーターをバイト型配列からint型に変換 Int32 len = BitConverter.ToInt32(client.HeaderBuffer, 0); //------------ // データー本体読み込み //------------ // データー本体用バイト型配列 // 後にデーター本体を、バイト型配列に格納する時に使う。 byte[] inBuffer = new byte[len]; // ストリームからデーター本体を読み込む。 client.pipeClient.Read(inBuffer, 0, len); // 取得したデーターをバイト型配列からstring型に変換 // (バイト型配列 ---> ユニコードstring 変換) string temp; // 取得文字を格納するオブジェクト StringBytesController.ChangeBinaryToUnicodeStr( inBuffer, "shift_jis", out temp); // サーバーに接続されたか確認。 if (temp == "A connection succeeded.") { // ストリームに対して、文字データーを読み書きするオブジェクトを生成 AccessStream ss = new AccessStream(pipeClient); // コマンド(命令)をサーバーへ送信。 ss.WriteString(client.CommandMessage, "shift_jis"); // サーバープロセスから通達されたメッセージを取得する。 client.ReceiveReply(client); } }