コード例 #1
0
        /// <summary>
        /// Transmits the message via the UDP broadcast client.
        /// </summary>
        /// <param name="toEP">The target endpoint.</param>
        /// <param name="msg">The message.</param>
        private void TransmitViaUdpBroadcast(ChannelEP toEP, Msg msg)
        {
            byte[] sendBuf;
            int    cbSend;
            int    cbMsg;

            msg._SetToChannel(toEP);
            msg._SetFromChannel(localEP);
            msg._Trace(router, 2, "UDP: Send", null);

            using (TimedLock.Lock(router.SyncRoot))
            {
                // Initiate transmission of the message

                cbMsg   = Msg.Save(new EnhancedMemoryStream(msgBuf), msg);
                sendBuf = router.EncryptFrame(msgBuf, cbMsg);
                cbSend  = sendBuf.Length;

                Assertion.Validate(cbSend <= TcpConst.MTU - UdpBroadcastClient.MessageEnvelopeSize, "Message larger than UDP MTU.");

                try
                {
                    broadcastClient.Broadcast(sendBuf);
                }
                catch
                {
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Handles message packets received on the socket.
        /// </summary>
        /// <param name="ar">The async result.</param>
        private void OnSocketReceive(IAsyncResult ar)
        {
            int cb;
            Msg msg = null;

            byte[]     msgBuf;
            int        cbMsg;
            IPEndPoint fromEP = NetworkBinding.Any;

            using (TimedLock.Lock(router.SyncRoot))
            {
                if (!isOpen)
                {
                    return;
                }

                try
                {
                    cb = sock.EndReceiveFrom(ar, ref recvEP);
                    if (cb > 0)
                    {
                        msgBuf = router.DecryptFrame(recvBuf, cb, out cbMsg);
                        msg    = Msg.Load(new EnhancedMemoryStream(msgBuf));

                        fromEP = (IPEndPoint)recvEP;
                        msg._SetFromChannel(new ChannelEP(transport, fromEP));
                    }
                }
                catch (MsgException)
                {
                    // Ignore messages that can't be parsed
                }
                catch (Exception e)
                {
                    SysLog.LogException(e);
                }

                // Initiate the receive of the next message

                if (sock.IsOpen)
                {
                    try
                    {
                        sock.BeginReceiveFrom(recvBuf, 0, recvBuf.Length, SocketFlags.None, ref recvEP, onSocketReceive, null);
                    }
                    catch (Exception e)
                    {
                        SysLog.LogException(e, "LillTek UDP message channel is no longer able to receive messages.");
                    }
                }
            }

            if (msg != null)
            {
                msg._Trace(router, 2, "UDP: Recv", string.Format("From: {0}", fromEP));
                msg._Trace(router, 0, "Receive", string.Empty);
                router.OnReceive(this, msg);
            }
        }
コード例 #3
0
        /// <summary>
        /// Initiates a network connection to the message router at the
        /// specified network endpoint and then initiates the transmission
        /// of the message once the connection is established.
        /// </summary>
        /// <param name="ep">The remote router's endpoint.</param>
        /// <param name="msg">The message to be sent (or <c>null</c>).</param>
        public void Connect(IPEndPoint ep, Msg msg)
        {
            using (TimedLock.Lock(router.SyncRoot))
            {
                Assertion.Test(sock == null);
                sock    = new EnhancedSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                localEP = new ChannelEP(Transport.Tcp, router.NormalizeEP(router.TcpEP));

                sock.NoDelay           = !router.TcpDelay;
                sock.SendBufferSize    = router.TcpSockConfig.SendBufferSize;
                sock.ReceiveBufferSize = router.TcpSockConfig.ReceiveBufferSize;

                if (router.FragmentTcp)
                {
                    sock.SendMax    = 1;
                    sock.ReceiveMax = 1;
                }

                // Queue the channel initialization message and the message passed

                Msg initMsg;

                initMsg      = new TcpInitMsg(router.RouterEP, new MsgRouterInfo(router), isUplink, router.TcpEP.Port);
                initMsg._TTL = 1;

                Serialize(initMsg);
                Enqueue(initMsg);

                try
                {
                    SetLastAccess();
                    remoteEP = new ChannelEP(Transport.Tcp, router.NormalizeEP(ep));

                    if (msg != null)
                    {
                        msg._SetToChannel(remoteEP);
                        msg._SetFromChannel(localEP);
                        msg._Trace(router, 2, "TCP: Queue", null);

                        Serialize(msg);
                        Enqueue(msg);
                    }

                    router.Trace(2, "TCP: Outbound", "LocalEP=" + localEP.NetEP.ToString() + " remoteEP=" + remoteEP.NetEP.ToString(), null);
                    sock.BeginConnect(remoteEP.NetEP, new AsyncCallback(OnConnect), null);
                }
                catch (Exception e)
                {
                    router.Trace(string.Format(null, "TCP: Connect Failed [{0}]", ep), e);
                    router.OnTcpClose(this);
                    Close();
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// Private implementation of the Transmit() method that implements an
        /// option that disables queuing for the message passed.
        /// </summary>
        /// <param name="toEP">The target endpoint.</param>
        /// <param name="msg">The message.</param>
        /// <param name="queue">Indicates whether queuing should be enabled for this message.</param>
        private void Transmit(ChannelEP toEP, Msg msg, bool queue)
        {
            msg._SetToChannel(toEP);
            msg._SetFromChannel(localEP);
            msg._Trace(router, 2, "TCP: Send", null);

            // Serialize the message here rather than within the lock
            // below for better multiprocessor performance.

            Serialize(msg);

            // Initiate transmission of the message or queue it if other
            // messages are awaiting transmission (if queuing is enabled).

            try
            {
                using (TimedLock.Lock(router.SyncRoot))
                {
                    if (!connected || sending)
                    {
                        Enqueue(msg);
                        return;
                    }

                    // If there are already messages in the queue then add this
                    // message to the end of the queue and then dequeue a message
                    // from the front of the queue and send it.

                    if (queue && sendQueue.Count > 0)
                    {
                        Enqueue(msg);
                        msg = Dequeue();
                    }

                    // Initiate message transmission

                    sendBuf = msg._MsgFrame;
                    sending = true;
                    sendPos = 0;
                    cbSend  = sendBuf.Length;

                    sock.BeginSend(sendBuf, sendPos, cbSend, SocketFlags.None, onSend, null);
                }
            }
            catch (Exception e)
            {
                TraceException(e);
                router.OnTcpClose(this);
                Close();
            }
        }
コード例 #5
0
        /// <summary>
        /// Queues the message passed rather than initiating an
        /// immediate transmission.
        /// </summary>
        /// <param name="toEP">The target endpoint.</param>
        /// <param name="msg">The message to queue.</param>
        internal void QueueTo(ChannelEP toEP, Msg msg)
        {
            msg._SetToChannel(toEP);
            msg._SetFromChannel(localEP);
            msg._Trace(router, 2, "TCP: Queue", null);

            Serialize(msg);

            using (TimedLock.Lock(router.SyncRoot))
            {
                msg._SetToChannel(toEP);
                Enqueue(msg);
            }
        }
コード例 #6
0
        /// <summary>
        /// Handles messages received from the UdpBroadcast client.
        /// </summary>
        /// <param name="sender">The UDP broadcast client.</param>
        /// <param name="args">Event arguments.</param>
        private void OnBroadcastReceive(object sender, UdpBroadcastEventArgs args)
        {
            Msg msg = null;

            byte[] msgBuf;
            int    cbMsg;
            int    cb;

            using (TimedLock.Lock(router.SyncRoot))
            {
                if (!isOpen)
                {
                    return;
                }

                try
                {
                    cb = args.Payload.Length;
                    if (cb > 0)
                    {
                        msgBuf = router.DecryptFrame(args.Payload, cb, out cbMsg);
                        msg    = Msg.Load(new EnhancedMemoryStream(msgBuf));

                        msg._SetFromChannel(new ChannelEP(transport, new IPEndPoint(args.SourceAddress, 0)));
                    }
                }
                catch (MsgException)
                {
                    // Ignore messages that can't be parsed
                }
                catch (Exception e)
                {
                    SysLog.LogException(e);
                }
            }

            if (msg != null)
            {
                msg._Trace(router, 2, "UDP: Broadcast Recv", string.Format("From: {0}", args.SourceAddress));
                msg._Trace(router, 0, "Receive", string.Empty);
                router.OnReceive(this, msg);
            }
        }
コード例 #7
0
        /// <summary>
        /// Handles message packet send completions on the socket.
        /// </summary>
        /// <param name="ar">The async result.</param>
        private void OnSend(IAsyncResult ar)
        {
            ChannelEP toEP;
            int       cb;
            int       cbMsg;

            using (TimedLock.Lock(router.SyncRoot))
            {
                if (!isOpen || sendMsg == null)
                {
                    return;
                }

                Assertion.Test(sendMsg != null);
                sendMsg = null;

                try
                {
                    cb = sock.EndSendTo(ar);
                    Assertion.Test(cb == cbSend);

                    if (sendQueue.Count > 0)
                    {
                        sendMsg = sendQueue.Dequeue();
                        toEP    = sendMsg._ToEP.ChannelEP;

                        sendMsg._SetFromChannel(localEP);

                        cbMsg   = Msg.Save(new EnhancedMemoryStream(msgBuf), sendMsg);
                        sendBuf = router.EncryptFrame(msgBuf, cbMsg);
                        cbSend  = sendBuf.Length;

                        Assertion.Validate(cbSend <= TcpConst.MTU, "Message larger than UDP MTU.");
                        sock.BeginSendTo(sendBuf, 0, cbSend, SocketFlags.None, router.NormalizeEP(toEP.NetEP), onSend, null);
                    }
                }
                catch
                {
                }
            }
        }
コード例 #8
0
        /// <summary>
        /// Transmits the message via the socket.
        /// </summary>
        /// <param name="toEP">The target endpoint.</param>
        /// <param name="msg">The message.</param>
        private void TransmitViaSocket(ChannelEP toEP, Msg msg)
        {
            int cbMsg;

            if (cloudEP != null && !multicastInit)
            {
                // Retry adding the socket to the multicast group if this didn't
                // work earlier.

                try
                {
                    this.sock.MulticastGroup = cloudEP.Address;
                    this.multicastInit       = true;
                }
                catch
                {
                    this.multicastInit = false;
                }
            }

            msg._SetToChannel(toEP);
            msg._SetFromChannel(localEP);
            msg._Trace(router, 2, "UDP: Send", null);

            using (TimedLock.Lock(router.SyncRoot))
            {
                if (sendMsg != null)
                {
                    // We're already in the process of transmitting
                    // a message so queue this one.

                    Enqueue(msg);
                    return;
                }

                // If there are already messages in the queue then queue
                // this one and then setup to transmit the first message
                // waiting in the queue.

                if (sendQueue.Count > 0)
                {
                    Enqueue(msg);
                    msg = sendQueue.Dequeue();
                }

                // Initiate transmission of the message

                sendMsg = msg;
                cbMsg   = Msg.Save(new EnhancedMemoryStream(msgBuf), sendMsg);
                sendBuf = router.EncryptFrame(msgBuf, cbMsg);
                cbSend  = sendBuf.Length;

                Assertion.Validate(cbSend <= TcpConst.MTU, "Message larger than UDP MTU.");

                try
                {
                    sock.BeginSendTo(sendBuf, 0, cbSend, SocketFlags.None, router.NormalizeEP(toEP.NetEP), onSend, null);
                }
                catch
                {
                    // Ignoring
                }
            }
        }