2

さまざまなマシンで実行されているC#で記述されたコンソールアプリケーションのシステムを入手しました。私はMSMQを使用しています。

私の質問は、コンソールアプリケーションを相互に通信させるにはどうすればよいですか?

MSMQ内のメッセージの数を知るために、他のアプリケーションからクエリできる新しいコンソールアプリケーションを作成したいので質問しています。

編集1:返信とコメントをありがとう!要件については、クエリの約10〜50/秒を見積もっています

4

3 に答える 3

2

これを実現するには、パイプを使用する必要があります。名前付きパイプと匿名パイプを参照してください。

パイプは次のように機能します。ホスト アプリケーション (コンソール アプリケーションを起動するアプリケーション) は、コンソール アプリケーションの std 出力をキャッチするパイプと、コンソール アプリケーションの std 入力に書き込む別のパイプを作成する必要があります。

私があなたに与えたリンクにはたくさんのコード例があります

また、ここにコード例があります (既存のパイプ StandardInput および StandardOutput を使用): cmd.exe コンソールを開始しますが、実際のコンソールではなく、上のレイヤーです...自分の目で確かめてください:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        private static StreamReader reader;

        static void Main(string[] args)
        {
            Process cmd = new Process();

            cmd.StartInfo.FileName = "cmd.exe";
            cmd.StartInfo.RedirectStandardInput = true;
            cmd.StartInfo.RedirectStandardOutput = true;
            cmd.StartInfo.UseShellExecute = false;

            cmd.Start();

            reader = cmd.StandardOutput;
            StreamWriter writer = cmd.StandardInput;


            Thread t = new Thread(new ThreadStart(writingThread));

            t.Start();

            //Just write everything we type to the cmd.exe process
            while (true) writer.Write((char)Console.Read());

        }

        public static void writingThread()
        {
            //Just write everything cmd.exe writes back to our console
            while (true) Console.Write((char)reader.Read());
        }
    }
}

2 つのプロセスhttp://msdn.microsoft.com/en-us/library/system.net.sockets.socket間のリモート通信用に、StreamReader と StreamWriter をポート接続 (ソケット) バッファーに置き換えることで、同じ結果を得ることができます 。 .aspx

侵入の可能性を最小限に抑えるために、通信を保護することをお勧めします

これはソケットを介した通信の例です...現在、これは1つのプログラムで実行されていますが、すべてが別々のスレッド上にあり、通信が2つの別々のマシン上にある場合に機能します:サーバーはプロセスcmdを制御するものです。 exe であり、クライアントはビューアー/ライターです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Net.Sockets;
using System.Net;

namespace ConsoleApplication1
{
    class Program
    {
        private static StreamReader reader;
        private static StreamWriter writer;

        static void Main(string[] args)
        {
            //Server initialisation 

            Process cmdServer = new Process();

            cmdServer.StartInfo.FileName = "cmd.exe";
            cmdServer.StartInfo.RedirectStandardInput = true;
            cmdServer.StartInfo.RedirectStandardOutput = true;
            cmdServer.StartInfo.UseShellExecute = false;

            cmdServer.Start();

            reader = cmdServer.StandardOutput;
            writer = cmdServer.StandardInput;


            Thread t1 = new Thread(new ThreadStart(clientListener));
            t1.Start();
            Thread t2 = new Thread(new ThreadStart(clientWriter));
            t2.Start();
            Thread t3 = new Thread(new ThreadStart(serverListener));
            t3.Start();
            Thread t4 = new Thread(new ThreadStart(serverWriter));
            t4.Start();


        }

        public static void clientWriter()
        {
            Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            Int32 size = 0;
            Byte[] buff = new Byte[1024];

            sock.Connect(IPAddress.Parse("127.0.0.1"), 4357);
            Console.WriteLine("clientWriter connected");

            while (true)
            {
                String line = Console.ReadLine();
                line += "\n";
                Char[] chars = line.ToArray();
                size = chars.Length;
                if (size > 0)
                {
                    buff = Encoding.Default.GetBytes(chars);
                    //Console.WriteLine("Sending \"" + new String(chars, 0, size) + "\"");
                    sock.Send(buff, size, 0);
                }
            }
        }

        /// <summary>
        /// Local client that listens to what the server sends on port 4356
        /// </summary>
        public static void clientListener()
        {
            Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            sock.Bind(new IPEndPoint(IPAddress.Any, 4356));
            sock.Listen(0);

            Int32 size = 0;
            Byte[] buff = new Byte[1024];
            Char[] cbuff = new Char[1024];

            while (true)
            {
                Console.WriteLine("clientListener Waiting for connection");
                sock = sock.Accept();
                Console.WriteLine("clientListener Connection accepted " + ((sock.Connected)?"Connected" : "Not Connected"));

                while ((size = sock.Receive(buff)) > 0)
                {
                    for (int i = 0; i < size; i++) cbuff[i] = (Char)buff[i];
                    Console.Write(cbuff, 0, size);
                }

                sock.Close();

            }
        }

        /// <summary>
        /// Remote server that listens to what the client sends on port 4357
        /// </summary>
        public static void serverListener()
        {
            Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            sock.Bind(new IPEndPoint(IPAddress.Any, 4357));
            sock.Listen(0);

            Int32 size = 0;
            Byte[] buff = new Byte[1024];
            Char[] cbuff = new Char[1024];

            while (true)
            {
                Console.WriteLine("serverListener Waiting for connection");
                sock = sock.Accept();
                Console.WriteLine("serverListener Connection accepted " + ((sock.Connected) ? "Connected" : "Not Connected"));

                while ((size = sock.Receive(buff)) > 0)
                {
                    for (int i = 0; i < size; i++) cbuff[i] = (Char)buff[i];
                    //Console.WriteLine("Received \"" + new String(cbuff,0,size) + "\"");
                    writer.Write(cbuff, 0, size);
                }

            }
        }

        /// <summary>
        /// Remote server that writes the output of the colsole application through the socket
        /// </summary>
        public static void serverWriter()
        {
            Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            Int32 size = 0;
            Byte[] buff = new Byte[1024];
            Char[] cbuff = new Char[1024];

            sock.Connect(IPAddress.Parse("127.0.0.1"), 4356);

            Console.WriteLine("serverWriter connected");

            while (true)
            {
                size = reader.Read(cbuff, 0, 1024);
                if (size > 0)
                {
                    for (int i = 0; i < size; i++) buff[i] = (Byte)cbuff[i];
                    sock.Send(buff, 0, size, 0);
                }
            }
        }
    }
}
于 2012-11-18T07:05:57.433 に答える
1

WCF。WCF、WCF、WCF、WCF。

車輪の再発明を気にせず、通信にWCFを使用するだけで、詳細(パイプまたはその他のメカニズムを使用するかどうか)について心配する必要があります。

于 2012-11-18T07:55:29.713 に答える
1

テスト可能で拡張可能 - コンピュータ間で動作するように簡単に変更できます。

いくつかの方法があります。「名前付きパイプ」は、WCF を使用して簡単に実現できます。非常にテストしやすいのでいいです。

メモリ マップ ファイルを使用できる最高のパフォーマンスhttp://weblogs.asp.net/gunnarpeipman/archive/2009/06/21/net-framework-4-0-using-memory-mapped-files.aspx

彼らは驚くべきパフォーマンスを持っています。しかし、テストするのはそれほど難しくありません。

最も簡単な方法 - トラフィックが非常に少ない場合は、レジストリを使用できます。C# には、スレッドセーフで高速な Regisrty クラスがあります。

于 2012-11-18T07:30:36.853 に答える