Example #1
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();
            }
        }
Example #2
0
            public int Send(byte[] buf)
            {
                Reset();
                sock.BeginSend(buf, 0, buf.Length, SocketFlags.None, onSendBuf, null);
                asyncEvent.WaitOne(MaxWaitTime, false);
                Verify();

                return(cbTransfer);
            }
Example #3
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));
                }
            }
        }