Example #1
0
            private void OnUdpReceive(IAsyncResult ar)
            {
                try
                {
                    var cbRecv   = udpSock.EndReceiveFrom(ar, ref udpRemoteEP);
                    var remoteEP = (IPEndPoint)udpRemoteEP;
                    var prefix   = PadPrefix(string.Format("UDP[{0}:{1}]:", remoteEP.Address, remoteEP.Port));

                    lock (syncLock)
                    {
                        Debug.WriteLine(string.Format("{0} Echoing [{1}] bytes", prefix, cbRecv));
                    }

                    var udpSendBuf = Helper.Extract(udpRecvBuf, 0, cbRecv);

                    udpSock.BeginSendTo(udpSendBuf, 0, cbRecv, SocketFlags.None, remoteEP,
                                        ar2 =>
                    {
                        try
                        {
                            udpSock.EndSendTo(ar2);
                        }
                        catch (SocketClosedException)
                        {
                            return;
                        }
                        catch
                        {
                            // Ignore
                        }
                    },
                                        null);

                    if (UdpReceived != null)
                    {
                        UdpReceived(this, new NetReflectorEventArgs()
                        {
                            Endpoint = remoteEP, Data = udpSendBuf
                        });
                    }

                    udpSock.BeginReceiveFrom(udpRecvBuf, 0, udpRecvBuf.Length, SocketFlags.None, ref udpRemoteEP, onUdpReceive, null);
                }
                catch (SocketClosedException)
                {
                    return;
                }
                catch (Exception e)
                {
                    lock (syncLock)
                    {
                        Debug.WriteLine(string.Format("*** {0}: {1}", e.GetType().Name, e.Message));
                    }
                }
            }
Example #2
0
        /// <summary>
        /// Initiates the transmission of bytes from a buffer to the remote side of the connection.
        /// </summary>
        /// <param name="buffer">The source buffer.</param>
        /// <param name="offset">Index of the first byte to be transmitted.</param>
        /// <param name="count">Number of bytes to be transmitted.</param>
        /// <param name="callback">The delegate to be called when the operation completes (or <c>null</c>).</param>
        /// <param name="state">Application specific state.</param>
        /// <returns>
        /// An <see cref="IAsyncResult" /> instance to be used to track the progress of the
        /// operation and to eventually be passed to the <see cref="EndSend" /> method.
        /// </returns>
        /// <exception cref="InvalidOperationException">Thrown if the socket is not connected or if another send operation is already pending for TCP connections.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="buffer" /> is <c>null</c>.</exception>
        /// <exception cref="IndexOutOfRangeException">Thrown if <paramref name="offset" /> and <paramref name="count" /> specify bytes outside of the <paramref name="buffer" />.</exception>
        /// <remarks>
        /// <note>
        /// Only one send operation may be outstanding at a time for any TCP connections.  Multiple sends
        /// may be in progress for UDP connections.
        /// </note>
        /// <note>
        /// For TCP connections, the send operation will continue until all bytes have been transmitted to the
        /// remote endpoint.  For UDP connections, only a single packet with as many bytes as may be delivered
        /// by the underlying infrastructure will be send.
        /// </note>
        /// <note>
        /// All successful calls to <see cref="BeginSend" /> must eventually be followed by a call to <see cref="EndSend" />.
        /// </note>
        /// </remarks>
        public IAsyncResult BeginSend(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }

            if (offset < 0 || count < 0 || offset + count > buffer.Length + 1)
            {
                throw new IndexOutOfRangeException(string.Format("[LiteSocket.Send: offset={0}] and [count={1}] is not valid for buffer of length [{2}].", offset, count, buffer.Length));
            }

            lock (syncLock)
            {
                if (isTcp)
                {
                    if (!Connected)
                    {
                        throw new InvalidOperationException("Socket is not connected.");
                    }

                    if (tcpSendPending)
                    {
                        throw new InvalidOperationException("LiteSocket.Send: Another send operation is already pending on this TCP socket.");
                    }

                    try
                    {
                        tcpSendPending = true;

                        return(sock.BeginSend(buffer, offset, count, SocketFlags.None, callback, state));
                    }
                    catch
                    {
                        tcpSendPending = false;
                        throw;
                    }
                }
                else
                {
                    return(sock.BeginSendTo(buffer, offset, count, SocketFlags.None, udpRemoteEndPoint, callback, state));
                }
            }
        }
Example #3
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
                }
            }
        }