示例#1
0
        /// <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));
        }