protected Queue <NetQItem> m_SendQueue = new Queue <NetQItem>(); // packet send queue

        /// <summary>
        /// Sends arbitrary bytes of data across the wire.  Note that if the remote endpoint can't decipher the data
        /// as a known packet, the connection will be dropped by that endpoint immediately.
        /// </summary>
        /// <param name="data">bytes to send</param>
        public virtual int Send(byte[] data, PacketFlags flags)
        {
            SocketDebug(32);
            //Log.LogMsg("@__@ Monitor Enter");
            if (!OwningConnection.IsAlive)
            {
                Log.LogMsg("DuplexBlockingTransit - cant send data because owning connection isn't alive. MyTcpSocket == Null -> " + (OwningConnection.MyTCPSocket == null));
                Log.LogMsg("Can't send on socket " + OwningConnection.MyTCPSocket.Handle.ToString() + " with socket error reading " + m_LastTCPReceiveStatus.ToString());
                OwningConnection.KillConnection("Couldn't send. Connection has been closed.");
                return(-1);
            }
            SocketDebug(33);
            // Log.LogMsg("==>Sending " + data.Length.ToString() + " bytes.");
            try
            {
                bool isUDP = (flags & PacketFlags.UDP) != 0;
                if (isUDP)
                {
                    SocketDebug(34);
                    if (!OwningConnection.CanSendUDP)
                    {
                        Log.LogMsg("!!! Tried sending UDP packet when the connection wasn't yet ready to send UDP. Dropping packet.");
                        return(0);
                    }

                    SocketDebug(35);
                    // Don't allow fragmenting UDP packets
                    if (data.Length > 1024)
                    {
                        Log.LogMsg("Message exceeded UDP size of 1024 bytes. Sending via TCP instead.");
                        flags &= ~PacketFlags.UDP;
                    }
                }

                SocketDebug(36);
                NetQItem qi = new NetQItem();
                qi.Flags = flags;
                qi.Data  = data;
                qi.IsUDP = isUDP;
                m_SendQueue.Enqueue(qi);
                Log.LogMsg("Send queue now has " + m_SendQueue.Count.ToString() + " items in it.");
                SocketDebug(37);
                return(1);
            }
            catch (Exception sendExc)
            {
                Log.LogMsg("DuplexBlockingTransit - Failed to send data. " + sendExc.Message);
                return(-1);;
            }

            return(1);
        }
Пример #2
0
        protected Queue <NetQItem> m_SendQueue = new Queue <NetQItem>(); // packet send queue

        /// <summary>
        /// Sends arbitrary bytes of data across the wire.  Note that if the remote endpoint can't decipher the data
        /// as a known packet, the connection will be dropped by that endpoint immediately.
        /// </summary>
        /// <param name="data">bytes to send</param>
        public virtual int Send(byte[] data, PacketFlags flags)
        {
            //Log.LogMsg("@__@ Monitor Enter");
            if (!OwningConnection.IsAlive)
            {
                return(-1);
            }

            //Log.LogMsg("==>Sending " + data.Length.ToString() + " bytes.");
            try
            {
                bool isUDP = (flags & PacketFlags.UDP) != 0;
                if (isUDP)
                {
                    if (!OwningConnection.CanSendUDP)
                    {
                        Log.LogMsg("!!! Tried sending UDP packet when the connection wasn't yet ready to send UDP. Dropping packet.");
                        return(0);
                    }

                    // Don't allow fragmenting UDP packets
                    if (data.Length > 1024)
                    {
                        Log.LogMsg("Message exceeded UDP size of 1024 bytes. Sending via TCP instead.");
                        flags &= ~PacketFlags.UDP;
                    }
                }

                lock (m_SendQueue)
                {
                    NetQItem qi = new NetQItem();
                    qi.Flags = flags;
                    qi.Data  = data;
                    qi.IsUDP = isUDP;
                    m_SendQueue.Enqueue(qi);

                    Monitor.Pulse(m_SendQueue);
                    return(1);
                }
            }
            catch (Exception sendExc)
            {
                return(-1);;
            }

            return(1);
        }
Пример #3
0
        /// <summary>
        /// Sends arbitrary bytes of data across the wire.  Note that if the remote endpoint can't decipher the data
        /// as a known packet, the connection will be dropped by that endpoint immediately.  
        /// </summary>
        /// <param name="data">bytes to send</param>
        public virtual int Send(byte[] data, PacketFlags flags)
        {
            //Log.LogMsg("@__@ Monitor Enter");
            if (!OwningConnection.IsAlive)
            {
                return -1;
            }

            //Log.LogMsg("==>Sending " + data.Length.ToString() + " bytes.");
            try
            {
                bool isUDP = (flags & PacketFlags.UDP) != 0;
                if (isUDP)
                {
                    if (!OwningConnection.CanSendUDP)
                    {
                        Log.LogMsg("!!! Tried sending UDP packet when the connection wasn't yet ready to send UDP. Dropping packet.");
                        return 0;
                    }

                    // Don't allow fragmenting UDP packets
                    if (data.Length > 1024)
                    {
                        Log.LogMsg("Message exceeded UDP size of 1024 bytes. Sending via TCP instead.");
                        flags &= ~PacketFlags.UDP;
                    }
                }

                lock (m_SendQueue)
                {
                    NetQItem qi = new NetQItem();
                    qi.Flags = flags;
                    qi.Data = data;
                    qi.IsUDP = isUDP;
                    m_SendQueue.Enqueue(qi);

                    Monitor.Pulse(m_SendQueue);
                    return 1;
                }

            }
            catch (Exception sendExc)
            {
                return -1; ;
            }

            return 1;
        }
Пример #4
0
        /// <summary>
        /// Gets called when a send operation resolves.
        /// </summary>
        private void OnSendResolved(SocketAsyncEventArgs args, SockState state)
        {
            //// Log.LogMsg("Testy 13");
            try
            {
                OwningConnection.SentBytes(state.PacketBufferPointer.Position);
                bool isUDP = (state.Flags & PacketFlags.UDP) != 0;
                //Log.LogMsg("==>#### Async SEND Op Completed - #" + ((SockState)args.UserToken).ID.ToString() + "#");
                if (args.SocketError == SocketError.Success)
                {
                    //// Log.LogMsg("Testy 14");
                    state.PacketBufferPointer.Advance(args.BytesTransferred);
                    if (state.PacketBufferPointer.Position >= state.PacketBuffer.Length)
                    {
                        OwningConnection.PacketSent();
                        // Done sending packet.
                        state.Reset();
                        //Log.LogMsg("==>Done sending packet. Sent " + state.PacketBufferPointer.Position.ToString() + " bytes.");

                        // done sending packet, see if we have anything in the queue ready to go
                        bool             more  = false;
                        Queue <NetQItem> sendQ = isUDP ? m_SendQueueUDP : m_SendQueue;
                        lock (sendQ)
                        {
                            if (sendQ.Count > 0)
                            {
                                NetQItem itm = sendQ.Dequeue();
                                state.PacketBuffer = itm.Data;
                                state.Flags        = itm.Flags;
                                more = true;
                            }
                            else
                            {
                                // release the sending lock
                                if (isUDP)
                                {
                                    //Log.LogMsg("UDP send queue emptied.");
                                    Interlocked.Exchange(ref m_SendingUDP, 0);
                                }
                                else
                                {
                                    //Log.LogMsg("TCP send queue emptied.");
                                    Interlocked.Exchange(ref m_Sending, 0);
                                }
                            }
                        }

                        if (more)
                        {
                            //// Log.LogMsg("Testy 15");
                            SendBuffer(args, state, isUDP);
                        }

                        return;
                    }
                    else
                    {
                        //// Log.LogMsg("Testy 16");
                        // not done sending.  send again.
                        //Log.LogMsg("==>Continuing send.  " + state.PacketBufferPointer.Position.ToString() + " / " + state.PacketBuffer.Length.ToString() + " sent so far.");
                        SendBuffer(args, state, isUDP);
                    }
                }
                else
                {
                    //If we are in this else-statement, there was a socket error.
                    OwningConnection.KillConnection("Error sending packet. " + args.SocketError.ToString());
                }
            }
            catch (Exception ex)
            {
                //// Log.LogMsg("Testy 17");
                Log.LogMsg("Failed to ProcessSend. " + ex.Message);
                OwningConnection.KillConnection("Send error. " + ex.Message);
            }
        }
Пример #5
0
        /// <summary>
        /// Sends arbitrary bytes of data across the wire.  Note that if the remote endpoint can't decipher the data
        /// as a known packet, the connection will be dropped by that endpoint immediately.
        /// </summary>
        /// <param name="data">bytes to send</param>
        public virtual int Send(byte[] data, PacketFlags flags)
        {
            //Log.LogMsg("@__@ Monitor Enter");
            if (!OwningConnection.IsAlive)
            {
                //// Log.LogMsg("Testy 3");
                return(-1);
            }

            //Log.LogMsg("==>Sending " + data.Length.ToString() + " bytes.");
            try
            {
                bool isUDP = (flags & PacketFlags.UDP) != 0;

#if SILVERLIGHT
                // Silverlight can't do UDP and it can only send Async, i.e. Non-Blocking
                isUDP = false;
                OwningConnection.BlockingMode = false;
#endif
                if (isUDP)
                {
                    //// Log.LogMsg("Testy 4");
                    if (!OwningConnection.CanSendUDP)
                    {
                        Log.LogMsg("!!! Tried sending UDP packet when the connection wasn't yet ready to send UDP. Dropping packet.");
                        return(0);
                    }

                    // Don't allow fragmenting UDP packets
                    if (data.Length > m_SendArgsUDP.Buffer.Length && data.Length > 1024)
                    {
                        Log.LogMsg("Message exceeded UDP size. Sending via TCP instead.");
                        flags &= ~PacketFlags.UDP;
                    }
                }

                if (!OwningConnection.BlockingMode)
                {
                    // send via asyncsend, but only one send op can be in progress at one time
                    // out of order packets can happen because the actual send is done with I/O completion ports and if multiple
                    // packets get submitted to the I/O queue they could be processed out of order, especially if the packet are of wildly differing sizes
                    if (isUDP)
                    {
                        //// Log.LogMsg("Testy 5");
                        lock (m_SendQueueUDP)
                        {
                            if (1 == Interlocked.Exchange(ref m_SendingUDP, 1))
                            {
                                // failed to get the lock - a message is in progress.  queue message.
                                NetQItem qi = new NetQItem();
                                qi.Flags = flags;
                                qi.Data  = data;
                                m_SendQueueUDP.Enqueue(qi);
                                Log.LogMsg("Queueing UDP packet. Now " + m_SendQueueUDP.Count.ToString() + " in Queue.");
                                return(1);
                            }
                            //Log.LogMsg("Acquired UDP send lock.");
                        }
                    }
                    else
                    {
                        lock (m_SendQueue)
                        {
                            if (1 == Interlocked.Exchange(ref m_Sending, 1))
                            {
                                // failed to get the lock - a message is in progress.  queue message.
                                NetQItem qi = new NetQItem();
                                qi.Flags = flags;
                                qi.Data  = data;
                                m_SendQueue.Enqueue(qi);
                                Log.LogMsg("Queueing TCP packet. Now " + m_SendQueue.Count.ToString() + " in Queue.");
                                return(1);
                            }
                            //Log.LogMsg("Acquired TCP send lock.");
                        }
                    }
                }

                SocketAsyncEventArgs args  = isUDP ? m_SendArgsUDP : m_SendArgs;
                SockState            state = args.UserToken as SockState;
                state.Flags        = flags;
                state.PacketBuffer = data;
                //// Log.LogMsg("Testy 6");
                SendBuffer(args, state, isUDP);
            }
            catch (Exception sendExc)
            {
                OwningConnection.KillConnection(sendExc.Message);
                return(-1);;
            }

            return(1);
        }
Пример #6
0
        /// <summary>
        /// Sends arbitrary bytes of data across the wire.  Note that if the remote endpoint can't decipher the data
        /// as a known packet, the connection will be dropped by that endpoint immediately.  
        /// </summary>
        /// <param name="data">bytes to send</param>
        public virtual int Send(byte[] data, PacketFlags flags)
        {
            //Log.LogMsg("@__@ Monitor Enter");
            if (!OwningConnection.IsAlive)
            {
                //// Log.LogMsg("Testy 3");
                return -1;
            }

            //Log.LogMsg("==>Sending " + data.Length.ToString() + " bytes.");
            try
            {
                bool isUDP = (flags & PacketFlags.UDP) != 0;

            #if SILVERLIGHT
                // Silverlight can't do UDP and it can only send Async, i.e. Non-Blocking
                isUDP = false;
                OwningConnection.BlockingMode = false;
            #endif
                if (isUDP)
                {
                    //// Log.LogMsg("Testy 4");
                    if (!OwningConnection.CanSendUDP)
                    {
                        Log.LogMsg("!!! Tried sending UDP packet when the connection wasn't yet ready to send UDP. Dropping packet.");
                        return 0;
                    }

                    // Don't allow fragmenting UDP packets
                    if (data.Length > m_SendArgsUDP.Buffer.Length && data.Length > 1024)
                    {
                        Log.LogMsg("Message exceeded UDP size. Sending via TCP instead.");
                        flags &= ~PacketFlags.UDP;
                    }
                }

                if (!OwningConnection.BlockingMode)
                {
                    // send via asyncsend, but only one send op can be in progress at one time
                    // out of order packets can happen because the actual send is done with I/O completion ports and if multiple
                    // packets get submitted to the I/O queue they could be processed out of order, especially if the packet are of wildly differing sizes
                    if (isUDP)
                    {
                        //// Log.LogMsg("Testy 5");
                        lock (m_SendQueueUDP)
                        {
                            if (1 == Interlocked.Exchange(ref m_SendingUDP, 1))
                            {
                                // failed to get the lock - a message is in progress.  queue message.
                                NetQItem qi = new NetQItem();
                                qi.Flags = flags;
                                qi.Data = data;
                                m_SendQueueUDP.Enqueue(qi);
                                Log.LogMsg("Queueing UDP packet. Now " + m_SendQueueUDP.Count.ToString() + " in Queue.");
                                return 1;
                            }
                            //Log.LogMsg("Acquired UDP send lock.");
                        }
                    }
                    else
                    {
                        lock (m_SendQueue)
                        {
                            if (1 == Interlocked.Exchange(ref m_Sending, 1))
                            {
                                // failed to get the lock - a message is in progress.  queue message.
                                NetQItem qi = new NetQItem();
                                qi.Flags = flags;
                                qi.Data = data;
                                m_SendQueue.Enqueue(qi);
                                Log.LogMsg("Queueing TCP packet. Now " + m_SendQueue.Count.ToString() + " in Queue.");
                                return 1;
                            }
                            //Log.LogMsg("Acquired TCP send lock.");
                        }
                    }
                }

                SocketAsyncEventArgs args = isUDP ? m_SendArgsUDP : m_SendArgs;
                SockState state = args.UserToken as SockState;
                state.Flags = flags;
                state.PacketBuffer = data;
                //// Log.LogMsg("Testy 6");
                SendBuffer(args, state, isUDP);
            }
            catch (Exception sendExc)
            {
                OwningConnection.KillConnection(sendExc.Message);
                return -1; ;
            }

            return 1;
        }
Пример #7
0
        /// <summary>
        /// Sends arbitrary bytes of data across the wire.  Note that if the remote endpoint can't decipher the data
        /// as a known packet, the connection will be dropped by that endpoint immediately.  
        /// </summary>
        /// <param name="data">bytes to send</param>
        public virtual int Send(byte[] data, PacketFlags flags)
        {
            //Log.LogMsg("@__@ Monitor Enter");
            if (!IsAlive)
            {
                KillConnection("Couldn't send. Connection has been closed.");
                return -1;
            }
            try
            {
                bool isUDP = (flags & PacketFlags.UDP) != 0;
                if (isUDP)
                {
                    if (!CanSendUDP)
                    {
                        Log.LogMsg("!!! Tried sending UDP packet when the connection wasn't yet ready to send UDP. Dropping packet.");
                        return 0;
                    }

                    // Don't allow fragmenting UDP packets
                    if (data.Length > 1024)
                    {
                        Log.LogMsg("Message exceeded UDP size of 1024 bytes. Sending via TCP instead.");
                        flags &= ~PacketFlags.UDP;
                    }
                }

                NetQItem qi = new NetQItem();
                qi.Flags = flags;
                qi.Data = data;
                qi.IsUDP = isUDP;
                m_SendQueue.Enqueue(qi);
                return 1;
            }
            catch (Exception sendExc)
            {
                Log.LogMsg("DuplexBlockingTransit - Failed to send data. " + sendExc.Message);
                return -1; ;
            }

            return 1;
        }
        /// <summary>
        /// Sends arbitrary bytes of data across the wire.  Note that if the remote endpoint can't decipher the data
        /// as a known packet, the connection will be dropped by that endpoint immediately.  
        /// </summary>
        /// <param name="data">bytes to send</param>
        public virtual int Send(byte[] data, PacketFlags flags)
        {
            SocketDebug(32);
            //Log.LogMsg("@__@ Monitor Enter");
            if (!OwningConnection.IsAlive)
            {
                Log.LogMsg("DuplexBlockingTransit - cant send data because owning connection isn't alive. MyTcpSocket == Null -> " + (OwningConnection.MyTCPSocket == null));
                Log.LogMsg("Can't send on socket " + OwningConnection.MyTCPSocket.Handle.ToString() + " with socket error reading " + m_LastTCPReceiveStatus.ToString());
                OwningConnection.KillConnection("Couldn't send. Connection has been closed.");
                return -1;
            }
            SocketDebug(33);
            // Log.LogMsg("==>Sending " + data.Length.ToString() + " bytes.");
            try
            {
                bool isUDP = (flags & PacketFlags.UDP) != 0;
                if (isUDP)
                {
                    SocketDebug(34);
                    if (!OwningConnection.CanSendUDP)
                    {
                        Log.LogMsg("!!! Tried sending UDP packet when the connection wasn't yet ready to send UDP. Dropping packet.");
                        return 0;
                    }

                    SocketDebug(35);
                    // Don't allow fragmenting UDP packets
                    if (data.Length > 1024)
                    {
                        Log.LogMsg("Message exceeded UDP size of 1024 bytes. Sending via TCP instead.");
                        flags &= ~PacketFlags.UDP;
                    }
                }

                SocketDebug(36);
                NetQItem qi = new NetQItem();
                qi.Flags = flags;
                qi.Data = data;
                qi.IsUDP = isUDP;
                m_SendQueue.Enqueue(qi);
                Log.LogMsg("Send queue now has " + m_SendQueue.Count.ToString() + " items in it.");
                SocketDebug(37);
                return 1;
            }
            catch (Exception sendExc)
            {
                Log.LogMsg("DuplexBlockingTransit - Failed to send data. " + sendExc.Message);
                return -1; ;
            }

            return 1;
        }