/// <summary>Thread関数</summary> public void invoke() { // 通信シーケンスは自分で設計する // (本サンプルはリクエスト・レスポンス型の通信シーケンス)。 NetworkStream ns = null; MemoryStream ms = null; byte[] buff = new byte[256]; byte[] byt = null; int bytSize = 0; string msg = ""; // スレッドID int managedThreadId = Thread.CurrentThread.ManagedThreadId; try { bool disConnect = false; ns = this.TCPCnn.GetStream(); // 接続メッセージを表示 this.SetResult_Svr( string.Format( "接続 - ThreadId:{0}", managedThreadId)); do { ms = new MemoryStream(); // 受信処理 while (true) { // メッセージ(の一部 - 256 byte)を受信 bytSize = ns.Read(buff, 0, buff.Length); //(待機) // 受信したメッセージをメモリに蓄積 ms.Write(buff, 0, bytSize); // 受信したメッセージを文字列に変換 msg = Encoding.UTF8.GetString(ms.ToArray()); // ここでは、シーケンス制御文字の // <end-send>が送られるまで受信を続行する。 if (msg.IndexOf("<end-send>") != -1) { // シーケンス制御文字を消去 msg = msg.Replace("<end-send>", ""); break; } // ここでは、シーケンス制御文字の // <end-connect>が送られるまで受信を続行する。 if (msg.IndexOf("<end-connect>") != -1) { // これがきたときに切断 disConnect = true; // シーケンス制御文字を消去 msg = msg.Replace("<end-connect>", ""); break; } } ms.Close(); // 受信メッセージを表示 this.SetResult_Svr( string.Format("({0})受信:{1}", managedThreadId, msg)); // 反転処理 msg = CmnClass.strrev(msg); // 送信処理 if (!disConnect) // <end-connect>の際は、接続がクライアントから切断されている。 { // 送信処理 byt = Encoding.UTF8.GetBytes(msg + "<end-send>"); ns.Write(byt, 0, byt.Length); // 送信メッセージを表示 this.SetResult_Svr( string.Format("({0})送信:{1}", managedThreadId, msg)); } } while (!disConnect); } finally { // TCPコネクションをクローズ ms.Close(); ns.Close(); this.TCPCnn.Close(); // 切断メッセージを表示 this.SetResult_Svr( string.Format( "切断 - ThreadId:{0}", managedThreadId)); } }
/// <summary>クライアント生成 - Writeスレッド関数</summary> private void WriteSharedMemory() { // 共有メモリ(サーバ) SharedMemory sm = null; // スレッドID int managedThreadId = Thread.CurrentThread.ManagedThreadId; try { // 共有メモリを生成(256バイト) sm = new SharedMemory("my-sm", 256, "my-mtx"); // マップ sm.Map(0, 0); // ロック sm.Lock(); // システム時間、ローカル時間の「Manage SYSTEMTIME構造体」 SYSTEMTIME[] csts = new SYSTEMTIME[2]; // システム時間 CmnWin32.GetSystemTime(out csts[0]); string systemTime = string.Format("{0:0000}/{1:00}/{2:00} {3:00}:{4:00}:{5:00}.{6:000}", csts[0].Year, csts[0].Month, csts[0].Day, csts[0].Hour, csts[0].Minute, csts[0].Second, csts[0].Milliseconds); // ローカル時間 CmnWin32.GetLocalTime(out csts[1]); string localTime = string.Format("{0:0000}/{1:00}/{2:00} {3:00}:{4:00}:{5:00}.{6:000}", csts[1].Year, csts[1].Month, csts[1].Day, csts[1].Hour, csts[1].Minute, csts[1].Second, csts[1].Milliseconds); // 共有メモリを初期化 sm.SetMemory(CmnClass.InitBuff(256), 256); // マーシャリング(「Unmanage SYSTEMTIME構造体」のバイト表現を取得) //// (1) //SYSTEMTIME cst = new SYSTEMTIME(); //int sizeCst = Marshal.SizeOf(cst); //byte[] cstBytes = new byte[sizeCst]; //byte[] cstsBytes = new byte[sizeCst * 2]; //Array.Copy(CustomMarshaler.StructureToBytes(csts[0]), 0, cstsBytes, 0, sizeCst); //Array.Copy(CustomMarshaler.StructureToBytes(csts[1]), 0, cstsBytes, sizeCst * 1, sizeCst); // (2) byte[] cstsBytes = CustomMarshaler.StructuresToBytes(new object[] { csts[0], csts[1] }, 2); // 共有メモリへ書き込む。 sm.SetMemory(cstsBytes, cstsBytes.Length); // 送信メッセージを表示 this.SetResult_Client( string.Format("({0})送信:{1}", managedThreadId, "\r\nsystemTime:" + systemTime + "\r\nlocalTime:" + localTime)); } catch (Exception ex) { // エラーを表示 this.SetResult_Client( string.Format("({0})エラー:{1}", managedThreadId, ex.ToString())); } finally { if (sm != null) { // 共有メモリをクローズ // アンロック&マネージ・アンマネージリソースの解放 sm.Close();// ←コメントアウトするとGC任せになるが、ミューテックスの解放が遅れる! } } }
/// <summary>サーバ起動 - listenerスレッド関数</summary> private void ListeningNamedPipe() { // 通信シーケンスは自分で設計する // (本サンプルはリクエスト・レスポンス型の通信シーケンス)。 // 名前付きパイプ(サーバ) NamedPipeServerStream np = null; MemoryStream ms = null; // スレッドID int managedThreadId = Thread.CurrentThread.ManagedThreadId; try { // 名前付きパイプ(サーバ)を生成 // ※ 双方向のメッセージ ストリーム(最大5個オープン可能) np = new NamedPipeServerStream( "mypipe", PipeDirection.InOut, 5); // Listening開始を表示 this.SetResult_Svr( string.Format("Listening開始! - ThreadId:{0}", managedThreadId)); np.WaitForConnection(); //(待機) // 接続を表示 this.SetResult_Svr( string.Format("接続 - ThreadId:{0}", managedThreadId)); // 終了させるまで延々と読み続ける。 bool disConnect = false; byte[] buff = new byte[256]; byte[] byt = null; int bytSize = 0; string msg = ""; do { ms = new MemoryStream(); // 受信処理 while (true) { // 送信元(=クライアント)毎に読み込むことができる。 bytSize = np.Read(buff, 0, buff.Length); // 受信したメッセージをメモリに蓄積 ms.Write(buff, 0, bytSize); // 受信したメッセージを文字列に変換 msg = Encoding.UTF8.GetString(ms.ToArray()); // ここでは、シーケンス制御文字の // <end-send>が送られるまで受信を続行する。 if (msg.IndexOf("<end-send>") != -1) { // シーケンス制御文字を消去 msg = msg.Replace("<end-send>", ""); break; } // ここでは、シーケンス制御文字の // <end-connect>が送られるまで受信を続行する。 if (msg.IndexOf("<end-connect>") != -1) { // これがきたときに切断 disConnect = true; // シーケンス制御文字を消去 msg = msg.Replace("<end-connect>", ""); break; } } // 受信メッセージを表示 this.SetResult_Svr( string.Format("({0})受信:{1}", managedThreadId, msg)); // 反転処理 msg = CmnClass.strrev(msg); // 送信処理 if (!disConnect) // <end-connect>の際は、接続がクライアントから切断されている。 { // 送信処理 byt = Encoding.UTF8.GetBytes(msg + "<end-send>"); np.Write(byt, 0, byt.Length); // 送信メッセージを表示 this.SetResult_Svr( string.Format("({0})送信:{1}", managedThreadId, msg)); } } while (!disConnect); } catch (Exception ex) { // エラーを表示 this.SetResult_Svr( string.Format("({0})エラー:{1}", managedThreadId, ex.ToString())); } finally { if (np != null) { // 名前付きパイプ(サーバ)をクローズ np.Close(); } } // 切断を表示 this.SetResult_Svr( string.Format("切断 - ThreadId:{0}", managedThreadId)); }