示例#1
0
    private void ListenerWork()
    {
        while (true)
        {
            _threadRunning     = true;
            _listenerCancelled = false;
            AsyncIO.ForceDotNet.Force();
            using (var server = new PairSocket())
            {
                server.Bind("tcp://*:" + port);

                while (!_listenerCancelled)
                {
                    Connected = _contactWatch.ElapsedMilliseconds < ContactThreshold;
                    byte[] frameBytes;
                    if (!server.TryReceiveFrameBytes(out frameBytes))
                    {
                        continue;
                    }
                    _contactWatch.Restart();
                    if (OnBytes != null && frameBytes != null)
                    {
                        OnBytes.Invoke(frameBytes);
                    }
                }

                server.Close();
            }
            NetMQConfig.Cleanup();
            _threadRunning = false;
        }
    }
示例#2
0
        public void BindAndConnect()
        {
            using (PairSocket bind = new PairSocket())
            {
                bind.Bind("inproc://test");
                Assert.That(!bind.HasOut);

                using (PairSocket connect = new PairSocket())
                {
                    connect.Connect("inproc://test");

                    Assert.That(connect.HasOut);
                    Assert.That(bind.HasOut);
                    Assert.That(!bind.HasIn);

                    Assert.That(connect.TrySendFrame("Hello"));
                    Assert.That(bind.HasIn);

                    string message;

                    Assert.That(bind.TryReceiveFrameString(out message));
                    Assert.That(message == "Hello");
                }
            }
        }
 private void ConnectionWork()
 {
     AsyncIO.ForceDotNet.Force();
     using (var pairSocket = new PairSocket()) {
         pairSocket.Options.ReceiveHighWatermark = 1000;
         if (_createConnection)
         {
             pairSocket.Bind("tcp://*:12345");
         }
         else
         {
             pairSocket.Connect("tcp://localhost:12345");
         }
         //Do one more loop in-case we send out a closing msg and then cancel the connection
         bool flushedBuffer = true;
         while (!_connectionCancelled || !flushedBuffer)
         {
             string frameString;
             while (pairSocket.TryReceiveFrameString(out frameString))
             {
                 _incomingMessageQueue.Enqueue(frameString);
             }
             while (_outgoingMessageQueue.TryDequeue(out frameString))
             {
                 pairSocket.SendFrame(frameString);
             }
             flushedBuffer = _connectionCancelled;
         }
         pairSocket.Close();
     }
     NetMQConfig.Cleanup();
 }
        public async Task CanGetState()
        {
            var serverAddress = "inproc://get-state-test";

            var serverSocket = new PairSocket();

            serverSocket.Bind(serverAddress);

            var processor = new TransactionProcessor(serverAddress);

            processor.Start();

            var context   = new TransactionContext(processor, "context");
            var addresses = new[] { "address1", "address2" };

            var task = Task.Run(() =>
            {
                var message = new Message();
                message.MergeFrom(serverSocket.ReceiveFrameBytes());

                Assert.Equal(MessageType.TpStateGetRequest, message.MessageType);

                var response = new TpStateGetResponse();
                response.Entries.AddRange(addresses.Select(x => new TpStateEntry {
                    Address = x, Data = ByteString.Empty
                }));

                serverSocket.SendFrame(response.Wrap(message, MessageType.TpStateGetResponse).ToByteArray());
            });

            var stateResponse = await context.GetStateAsync(addresses);

            Assert.Equal(addresses.Length, stateResponse.Count());
        }
示例#5
0
        /// <summary>
        /// Create new NetMQQueue.
        /// </summary>
        /// <param name="context">NetMQContext must be provided to the queue</param>
        /// <param name="capacity">The capacity of the queue, use zero for unlimited</param>
        public NetMQQueue(NetMQContext context, int capacity = 0)
        {
            m_context = context;
            m_queue   = new ConcurrentQueue <T>();
            m_writer  = m_context.CreatePairSocket();
            m_reader  = m_context.CreatePairSocket();

            if (capacity != 0)
            {
                m_writer.Options.SendHighWatermark = m_reader.Options.ReceiveHighWatermark = capacity / 2;
            }
            else
            {
                m_writer.Options.SendHighWatermark = m_reader.Options.ReceiveHighWatermark = 0;
            }

            m_eventDelegator = new EventDelegator <NetMQQueueEventArgs <T> >(() =>
            {
                m_reader.ReceiveReady += OnReceiveReady;
            }, () =>
            {
                m_reader.ReceiveReady -= OnReceiveReady;
            });

            string address = string.Format("inproc://NetMQQueue#{0}", Interlocked.Increment(ref s_sequence));

            m_reader.Bind(address);
            m_writer.Connect(address);

            m_dequeueMsg = new Msg();
            m_dequeueMsg.InitEmpty();
        }
示例#6
0
        public void RespondToPing()
        {
            // Setup
            var serverSocket = new PairSocket();

            serverSocket.Bind("inproc://stream-test");

            var pingMessage = new PingRequest().Wrap(MessageType.PingRequest);

            var stream = new Stream("inproc://stream-test");

            stream.Connect();

            // Run test case
            var task1 = Task.Run(() => serverSocket.SendFrame(pingMessage.ToByteString().ToByteArray()));
            var task2 = Task.Run(() =>
            {
                var message = new Message();
                message.MergeFrom(serverSocket.ReceiveFrameBytes());

                return(message);
            });

            Task.WhenAll(new[] { task1, task2 });

            var actualMessage = task2.Result;

            // Verify
            Assert.Equal(MessageType.PingResponse, actualMessage.MessageType);
            Assert.Equal(pingMessage.CorrelationId, actualMessage.CorrelationId);

            serverSocket.Unbind("inproc://stream-test");
            stream.Disconnect();
        }
示例#7
0
 private static void Node0(string url)
 {
     using (var s = new PairSocket())
     {
         s.Bind(url);
         SendReceive(s);
     }
 }
示例#8
0
        private NetMQActor(PairSocket self, PairSocket shim, IShimHandler shimHandler)
        {
            m_shimHandler = shimHandler;

            m_self = self;
            m_shim = shim;

            EventHandler <NetMQSocketEventArgs> onReceive = (sender, e) =>
                                                            m_receiveEvent.Fire(this, new NetMQActorEventArgs(this));

            EventHandler <NetMQSocketEventArgs> onSend = (sender, e) =>
                                                         m_sendEvent.Fire(this, new NetMQActorEventArgs(this));

            m_receiveEvent = new EventDelegator <NetMQActorEventArgs>(
                () => m_self.ReceiveReady += onReceive,
                () => m_self.ReceiveReady -= onReceive);

            m_sendEvent = new EventDelegator <NetMQActorEventArgs>(
                () => m_self.SendReady += onSend,
                () => m_self.SendReady -= onSend);

            var random = new Random();

            // Bind and connect pipe ends
            string actorName;
            string endPoint;

            while (true)
            {
                try
                {
                    actorName = string.Format("NetMQActor-{0}-{1}", random.Next(0, 10000), random.Next(0, 10000));
                    endPoint  = string.Format("inproc://{0}", actorName);
                    m_self.Bind(endPoint);
                    break;
                }
                catch (AddressAlreadyInUseException)
                {
                    // Loop around and try another random address
                }
            }

            m_shim.Connect(endPoint);

            m_shimThread = new Thread(RunShim)
            {
                Name = actorName
            };
            m_shimThread.Start();

            // Mandatory handshake for new actor so that constructor returns only
            // when actor has also initialised. This eliminates timing issues at
            // application start up.
            m_self.ReceiveSignal();
        }
示例#9
0
        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="address"></param>
        /// <param name="shimCreator"></param>
        protected WsSocket(string address, Func <int, string, BaseShimHandler> shimCreator)
        {
            Id = Interlocked.Increment(ref _id);

            _messagesPipe = new PairSocket();
            _messagesPipe.Bind($"inproc://wsrouter-{Id}");
            _messagesPipe.ReceiveReady += OnMessagePipeReceiveReady;
            _actor = NetMQActor.Create(ShimHandler = shimCreator(Id, address));

            _messagesPipe.ReceiveSignal();
        }
示例#10
0
文件: Actor.cs 项目: ryanjshaw/netmq
        public Actor(NetMQContext context,
                     IShimHandler <T> shimHandler, T state)
        {
            this.m_self = context.CreatePairSocket();
            this.m_shim = new Shim <T>(shimHandler, context.CreatePairSocket());
            this.m_self.Options.SendHighWatermark = 1000;
            this.m_self.Options.SendHighWatermark = 1000;
            this.m_state = state;

            m_receiveEventDelegatorHelper = new EventDelegatorHelper <NetMQActorEventArgs <T> >(() => m_self.ReceiveReady += OnReceive,
                                                                                                () => m_self.ReceiveReady += OnReceive);
            m_sendEventDelegatorHelper = new EventDelegatorHelper <NetMQActorEventArgs <T> >(() => m_self.SendReady += OnReceive,
                                                                                             () => m_self.SendReady += OnSend);

            //now binding and connect pipe ends
            string endPoint = string.Empty;

            while (true)
            {
                Action bindAction = () =>
                {
                    endPoint = GetEndPointName();
                    m_self.Bind(endPoint);
                };

                try
                {
                    bindAction();
                    break;
                }
                catch (NetMQException nex)
                {
                    if (nex.ErrorCode == ErrorCode.EFAULT)
                    {
                        bindAction();
                    }
                }
            }

            m_shim.Pipe.Connect(endPoint);

            //Initialise the shim handler
            this.m_shim.Handler.Initialise(state);

            //Create Shim thread handler
            CreateShimThread(state);

            //  Mandatory handshake for new actor so that constructor returns only
            //  when actor has also initialized. This eliminates timing issues at
            //  application start up.
            m_self.WaitForSignal();
        }
示例#11
0
        protected WSSocket(Func <int, IShimHandler> shimCreator)
        {
            int id = Interlocked.Increment(ref s_id);

            m_messagesPipe = new PairSocket();
            m_messagesPipe.Bind(string.Format("inproc://wsrouter-{0}", id));

            m_messagesPipe.ReceiveReady += OnMessagePipeReceiveReady;

            m_actor = NetMQActor.Create(shimCreator(id));

            m_messagesPipe.ReceiveSignal();
        }
示例#12
0
        private NetMQActor([NotNull] NetMQContext context, [NotNull] IShimHandler shimHandler)
        {
            m_shimHandler = shimHandler;

            m_self = context.CreatePairSocket();
            m_shim = context.CreatePairSocket();

            EventHandler <NetMQSocketEventArgs> onReceive = (sender, e) =>
                                                            m_receiveEvent.Fire(this, new NetMQActorEventArgs(this));

            EventHandler <NetMQSocketEventArgs> onSend = (sender, e) =>
                                                         m_sendEvent.Fire(this, new NetMQActorEventArgs(this));

            m_receiveEvent = new EventDelegator <NetMQActorEventArgs>(
                () => m_self.ReceiveReady += onReceive,
                () => m_self.ReceiveReady -= onReceive);

            m_sendEvent = new EventDelegator <NetMQActorEventArgs>(
                () => m_self.SendReady += onSend,
                () => m_self.SendReady -= onSend);

            var random = new Random();

            //now binding and connect pipe ends
            string endPoint;

            while (true)
            {
                try
                {
                    endPoint = string.Format("inproc://NetMQActor-{0}-{1}", random.Next(0, 10000), random.Next(0, 10000));
                    m_self.Bind(endPoint);
                    break;
                }
                catch (AddressAlreadyInUseException)
                {
                    // In case address already in use we continue searching for an address
                }
            }

            m_shim.Connect(endPoint);

            m_shimThread = new Thread(RunShim);
            m_shimThread.Start();

            // Mandatory handshake for new actor so that constructor returns only
            // when actor has also initialised. This eliminates timing issues at
            // application start up.
            m_self.ReceiveSignal();
        }
示例#13
0
        protected WSSocket(NetMQContext context, IShimHandler <int> shimHandler)
        {
            int id = Interlocked.Increment(ref s_id);

            m_context = context;

            m_messagesPipe = context.CreatePairSocket();
            m_messagesPipe.Bind(string.Format("inproc://wsrouter-{0}", id));

            m_messagesPipe.ReceiveReady += OnMessagePipeReceiveReady;

            m_actor = new Actor <int>(context, shimHandler, id);

            m_messagesPipe.WaitForSignal();
        }
示例#14
0
        public Actor(NetMQContext context,
                     IShimHandler <T> shimHandler, T state)
        {
            this.self = context.CreatePairSocket();
            this.shim = new Shim <T>(shimHandler, context.CreatePairSocket());
            this.self.Options.SendHighWatermark = 1000;
            this.self.Options.SendHighWatermark = 1000;
            this.state = state;

            //now binding and connect pipe ends
            string endPoint = string.Empty;

            while (true)
            {
                Action bindAction = () =>
                {
                    endPoint = GetEndPointName();
                    self.Bind(endPoint);
                };

                try
                {
                    bindAction();
                    break;
                }
                catch (NetMQException nex)
                {
                    if (nex.ErrorCode == ErrorCode.EFAULT)
                    {
                        bindAction();
                    }
                }
            }

            shim.Pipe.Connect(endPoint);

            //Initialise the shim handler
            this.shim.Handler.Initialise(state);

            //Create Shim thread handler
            CreateShimThread(state);
        }
示例#15
0
        public Actor(NetMQContext context, IShimHandler shimHandler, object[] args)
        {
            this.self = context.CreatePairSocket();
            this.shim = new Shim(shimHandler, context.CreatePairSocket());
            this.self.Options.SendHighWatermark = 1000;
            this.self.Options.SendHighWatermark = 1000;

            //now binding and connect pipe ends
            string endPoint = string.Empty;
            while (true)
            {
                Action bindAction = () =>
                {
                    endPoint = GetEndPointName();
                    self.Bind(endPoint);
                };

                try
                {
                    bindAction();
                    break;
                }
                catch (NetMQException nex)
                {
                    if (nex.ErrorCode == ErrorCode.EFAULT)
                    {
                        bindAction();
                    }
                }

            }

            shim.Pipe.Connect(endPoint);

            //Create Shim thread handler
            CreateShimThread(args);
        }
示例#16
0
        // Use this for initialization
        void Start()
        {
            //these are the fixed text objects that display the next-placed reactor's temperature and pressure
            temperatureValue = GameObject.Find("TemperatureValue");
            //build prefab and edge list dicts
            prefabs        = new Dictionary <string, GameObject>();
            managedObjects = new Dictionary <string, Dictionary <int, GameObject> >();
            managedLines   = new Dictionary <int, Dictionary <int, GameObject> >();
            edgeList       = new Dictionary <int, List <int> >();
            for (int i = 0; i < CommObjLabels.Count; i++)
            {
                prefabs[CommObjLabels[i]]        = CommObjPrefabs[i];
                managedObjects[CommObjLabels[i]] = new Dictionary <int, GameObject>();
            }
            managedObjects["source"][0] = GameObject.Find("source");
            //For rendering lines
            linemat = Resources.Load("ReactorLineMaterial", typeof(Material)) as Material;
            //set-up socket and poller
            VisionClient     = new SubscriberSocket();
            SimulationClient = new SubscriberSocket();
            ScreenshotServer = new PairSocket();
            VisionClient.Subscribe("vision-update");
            SimulationClient.Subscribe("simulation-update");
            UnityEngine.Debug.Log("set up the subscriptions at " + ServerUri);
            VisionClient.Connect(ServerUri);
            SimulationClient.Connect(ServerUri);
            ScreenshotServer.Bind(ScreenshotUri);
            Debug.Log("set up rep server at " + ScreenshotUri);
            VisionPoller = new NetMQPoller {
                VisionClient
            };                                              //, SimulationClient };
            SimulationPoller = new NetMQPoller {
                SimulationClient
            };
            ScreenshotPoller = new NetMQPoller {
                ScreenshotServer
            };
            //set-up event to add to task
            VisionResponseTask     = new TaskCompletionSource <byte[]>();
            SimulationResponseTask = new TaskCompletionSource <byte[]>();
            ScreenshotResponseTask = new TaskCompletionSource <string>();
            //ScreenshotStopResponseTask= new TaskCompletionSource<string[]>();
            SimulationClient.ReceiveReady += (s, a) => {
                var msg = a.Socket.ReceiveMultipartBytes();

                while (!SimulationResponseTask.TrySetResult(msg[1]))
                {
                    ;
                }
            };
            VisionClient.ReceiveReady += (z, b) => {
                var msg = b.Socket.ReceiveMultipartBytes();
                while (!VisionResponseTask.TrySetResult(msg[1]))
                {
                    ;
                }
            };
            ScreenshotServer.ReceiveReady += (s, a) =>
            {
                var msg = a.Socket.ReceiveFrameString();
                while (!ScreenshotResponseTask.TrySetResult(msg))
                {
                    ;
                }
            };
            //start polling thread
            VisionPoller.RunAsync();
            SimulationPoller.RunAsync();
            ScreenshotPoller.RunAsync();
        }
示例#17
0
        /// <summary>
        ///     <para>is the main thread of the broker</para>
        ///     <para>it spawns threads handling titanic operations</para>
        ///     <para>it receives GUID from Titanic Request Service and dispatches the requests
        ///     to available workers via MDPBroker</para>
        ///     <para>it also manages the appropriate changes in the file system as well as in queue</para>
        /// </summary>
        /// <param name="requestWorker">mdp worker processing the incoming requests for services</param>
        /// <param name="replyWorker">mdp worker processing incoming reply requests</param>
        /// <param name="closeWorker">mdp worker processing incoming close requests</param>
        /// <param name="serviceCallClient">mdp client forwarding requests to service providing mdp worker
        ///                                 via mdp broker and collecting replies</param>
        /// <exception cref="TerminatingException">The socket has been stopped.</exception>
        /// <exception cref="AddressAlreadyInUseException">The specified address is already in use.</exception>
        /// <exception cref="NetMQException">No IO thread was found, or the protocol's listener encountered an
        ///                                  error during initialization.</exception>
        /// <exception cref="ObjectDisposedException">thrown if the socket was already disposed</exception>
        public void Run( IMDPWorker requestWorker = null,
                          IMDPWorker replyWorker = null,
                          IMDPWorker closeWorker = null,
                          IMDPClient serviceCallClient = null)
        {
            using (var pipeStart = new PairSocket ())
            using (var pipeEnd = new PairSocket ())
            using (var cts = new CancellationTokenSource ())
            {
                // set up the inter thread communication pipe
                pipeStart.Bind (_titanic_internal_communication);
                pipeEnd.Connect (_titanic_internal_communication);

                // start the three child tasks
                var requestTask = Task.Run (() => ProcessTitanicRequest (pipeEnd, requestWorker), cts.Token);
                var replyTask = Task.Run (() => ProcessTitanicReply (replyWorker), cts.Token);
                var closeTask = Task.Run (() => ProcessTitanicClose (closeWorker), cts.Token);

                var tasks = new[] { requestTask, replyTask, closeTask };

                while (true)
                {
                    // wait for 1s for a new request from 'Request' to process
                    var input = pipeStart.Poll (PollEvents.PollIn, TimeSpan.FromMilliseconds (1000));

                    // any message available? -> process it
                    if ((input & PollEvents.PollIn) == PollEvents.PollIn)
                    {
                        // only one frame will be send [Guid]
                        var msg = pipeStart.ReceiveFrameString ();

                        Guid guid;
                        if (!Guid.TryParse (msg, out guid))
                            Log ("[TITANIC BROKER] Received a malformed GUID via pipe - throw it away");
                        else
                        {
                            Log (string.Format ("[TITANIC BROKER] Received request GUID {0} via pipe", msg));
                            // now we have a valid GUID - save it to disk for further use
                            m_io.SaveNewRequestEntry (guid);
                        }
                    }
                    //! now dispatch (brute force) the requests -> SHOULD BE MORE INTELLIGENT (!)
                    // dispatching will also worry about the handling of a potential reply
                    // dispatch only requests which have not been closed
                    foreach (var entry in m_io.GetNotClosedRequestEntries ().Where (entry => entry != default (RequestEntry)))
                    {
                        if (DispatchRequests (entry.RequestId, serviceCallClient))
                            m_io.SaveProcessedRequestEntry (entry);
                    }

                    //! should implement some sort of restart
                    // beware of the silently dieing threads - must be detected!
                    if (DidAnyTaskStopp (tasks))
                    {
                        // stopp all threads
                        cts.Cancel ();
                        // stop processing!
                        break;
                    }
                }
            }
        }
示例#18
0
        /// <summary>
        ///     <para>is the main thread of the broker</para>
        ///     <para>it spawns threads handling titanic operations</para>
        ///     <para>it receives GUID from Titanic Request Service and dispatches the requests
        ///     to available workers via MDPBroker</para>
        ///     <para>it also manages the appropriate changes in the file system as well as in queue</para>
        /// </summary>
        /// <param name="requestWorker">mdp worker processing the incoming requests for services</param>
        /// <param name="replyWorker">mdp worker processing incoming reply requests</param>
        /// <param name="closeWorker">mdp worker processing incoming close requests</param>
        /// <param name="serviceCallClient">mdp client forwarding requests to service providing mdp worker
        ///                                 via mdp broker and collecting replies</param>
        /// <exception cref="TerminatingException">The socket has been stopped.</exception>
        /// <exception cref="AddressAlreadyInUseException">The specified address is already in use.</exception>
        /// <exception cref="NetMQException">No IO thread was found, or the protocol's listener encountered an
        ///                                  error during initialization.</exception>
        /// <exception cref="ObjectDisposedException">thrown if the socket was already disposed</exception>
        public void Run([CanBeNull] IMDPWorker requestWorker     = null,
                        [CanBeNull] IMDPWorker replyWorker       = null,
                        [CanBeNull] IMDPWorker closeWorker       = null,
                        [CanBeNull] IMDPClient serviceCallClient = null)
        {
            using (var pipeStart = new PairSocket())
                using (var pipeEnd = new PairSocket())
                    using (var cts = new CancellationTokenSource())
                    {
                        // set up the inter thread communication pipe
                        pipeStart.Bind(_titanic_internal_communication);
                        pipeEnd.Connect(_titanic_internal_communication);

                        // start the three child tasks
                        var requestTask = Task.Run(() => ProcessTitanicRequest(pipeEnd, requestWorker), cts.Token);
                        var replyTask   = Task.Run(() => ProcessTitanicReply(replyWorker), cts.Token);
                        var closeTask   = Task.Run(() => ProcessTitanicClose(closeWorker), cts.Token);

                        var tasks = new[] { requestTask, replyTask, closeTask };

                        while (true)
                        {
                            // wait for 1s for a new request from 'Request' to process
                            var input = pipeStart.Poll(PollEvents.PollIn, TimeSpan.FromMilliseconds(1000));

                            // any message available? -> process it
                            if ((input & PollEvents.PollIn) == PollEvents.PollIn)
                            {
                                // only one frame will be send [Guid]
                                var msg = pipeStart.ReceiveFrameString();

                                Guid guid;
                                if (!Guid.TryParse(msg, out guid))
                                {
                                    Log("[TITANIC BROKER] Received a malformed GUID via pipe - throw it away");
                                }
                                else
                                {
                                    Log($"[TITANIC BROKER] Received request GUID {msg} via pipe");
                                    // now we have a valid GUID - save it to disk for further use
                                    m_io.SaveNewRequestEntry(guid);
                                }
                            }
                            //! now dispatch (brute force) the requests -> SHOULD BE MORE INTELLIGENT (!)
                            // dispatching will also worry about the handling of a potential reply
                            // dispatch only requests which have not been closed
                            foreach (var entry in m_io.GetNotClosedRequestEntries().Where(entry => entry != default(RequestEntry)))
                            {
                                if (DispatchRequests(entry.RequestId, serviceCallClient))
                                {
                                    m_io.SaveProcessedRequestEntry(entry);
                                }
                            }

                            //! should implement some sort of restart
                            // beware of the silently dieing threads - must be detected!
                            if (DidAnyTaskStopp(tasks))
                            {
                                // stop all threads
                                cts.Cancel();
                                // stop processing!
                                break;
                            }
                        }
                    }
        }
示例#19
0
        public static void Execute()
        {
            Console.WriteLine("Executing Pair test");

            _clientData = new byte[DataSize];
            _serverData = new byte[DataSize];
            var r = new Random();

            r.NextBytes(_clientData);
            r.NextBytes(_serverData);

            var clientThread = new Thread(
                () =>
            {
                var req = new PairSocket();
                req.Connect(InprocAddress);

                byte[] streamOutput = new byte[BufferSize];
                while (true)
                {
                    var sw = Stopwatch.StartNew();
                    for (int i = 0; i < Iter; i++)
                    {
                        var result = req.SendImmediate(_clientData);
                        Trace.Assert(result);
                        int read = 0;
                        using (var stream = req.ReceiveStream())
                            while (stream.Length != stream.Position)
                            {
                                read += stream.Read(streamOutput, 0, streamOutput.Length);
                            }
                        Trace.Assert(read == _serverData.Length);
                    }
                    sw.Stop();
                    var secondsPerSend = sw.Elapsed.TotalSeconds / (double)Iter;
                    Console.WriteLine("Pair Time {0} us, {1} per second, {2} mb/s ",
                                      (int)(secondsPerSend * 1000d * 1000d),
                                      (int)(1d / secondsPerSend),
                                      (int)(DataSize * 2d / (1024d * 1024d * secondsPerSend)));
                }
            });

            clientThread.Start();

            {
                var rep = new PairSocket();
                rep.Bind(InprocAddress);

                byte[] streamOutput = new byte[BufferSize];

                var sw = Stopwatch.StartNew();
                while (sw.Elapsed.TotalSeconds < 10)
                {
                    int read = 0;
                    using (var stream = rep.ReceiveStream())
                        while (stream.Length != stream.Position)
                        {
                            read += stream.Read(streamOutput, 0, streamOutput.Length);
                        }
                    rep.SendImmediate(_serverData);
                }

                clientThread.Abort();
            }
        }