Esempio n. 1
0
        internal void SendCommand(UdpCommandType cmd)
        {
            if (CheckCanSend(true) == UdpSendFailReason.None)
            {
                UdpStream stream = socket.GetWriteStream(mtu << 3, UdpSocket.HeaderBitSize);
                stream.WriteByte((byte)cmd, 8);

                UdpHeader header = MakeHeader(false);
                header.Pack(stream, socket);

                UdpHandle handle = MakeHandle(ref header);
                handle.Object = null;

                if (SendStream(stream, handle, false))
                {
                    // track stats
                    stats.PacketSent((uint)stream.Ptr >> 3);
                    socket.Stats.PacketSent((uint)stream.Ptr >> 3);
                }
                else
                {
                    // should we do something here?????
                }
            }
        }
        internal void SendObject(object o)
        {
            serializer.SendNext(o);

            while (serializer.HasQueuedObjects)
            {
                UdpSendFailReason reason = CheckCanSend(false);

                if (reason != UdpSendFailReason.None)
                {
                    while (serializer.HasQueuedObjects)
                    {
                        socket.Raise(UdpEvent.PUBLIC_OBJECT_SEND_FAILED, this, serializer.NextObject(), reason);
                    }

                    break;
                }

                UdpStream stream = socket.GetWriteStream(mtu << 3, UdpSocket.HeaderBitSize);
                object    obj    = serializer.NextObject();

                if (serializer.Pack(stream, ref obj))
                {
                    if (stream.Overflowing && (socket.Config.AllowPacketOverflow == false))
                    {
                        UdpLog.Error("stream to {0} is overflowing, not sending", endpoint.ToString());
                        socket.Raise(UdpEvent.PUBLIC_OBJECT_SEND_FAILED, this, obj, UdpSendFailReason.StreamOverflow);
                        return;
                    }

                    UdpHeader header = MakeHeader(true);
                    header.Pack(stream, socket);

                    UdpHandle handle = MakeHandle(ref header);
                    handle.Object = obj;

                    if (SendStream(stream, handle, alwaysSendMtu))
                    {
                        // track stats
                        stats.PacketSent((uint)stream.Ptr >> 3);
                        socket.Statistics.PacketSent((uint)stream.Ptr >> 3);

                        // push object to user thread
                        socket.Raise(UdpEvent.PUBLIC_OBJECT_SENT, this, obj);
                        Log.info(this, "SendObject##UdpSocket.HeaderBitSize: " + (UdpSocket.HeaderBitSize >> 3));
                        Log.info(this, "SendObject##size: " + (stream.Ptr >> 3));
                    }
                    else
                    {
                        socket.Raise(UdpEvent.PUBLIC_OBJECT_SEND_FAILED, this, obj, UdpSendFailReason.SocketError);
                    }
                }
                else
                {
                    socket.Raise(UdpEvent.PUBLIC_OBJECT_SEND_FAILED, this, obj, UdpSendFailReason.SerializerReturnedFalse);
                }
            }
        }
Esempio n. 3
0
        UdpHandle MakeHandle(ref UdpHeader header)
        {
            UdpHandle handle = new UdpHandle();

            handle.IsObject    = header.IsObject;
            handle.ObjSequence = header.ObjSequence;
            handle.SendTime    = header.Now;
            return(handle);
        }
        void AckHandles(UdpHeader header, bool updateRtt)
        {
            while (!sendWindow.Empty)
            {
                UdpHandle handle = sendWindow.Peek();

                int seqDistance = UdpMath.SeqDistance(handle.ObjSequence, header.AckSequence, UdpHeader.SEQ_PADD);
                if (seqDistance > 0)
                {
                    break;
                }

                if (handle.IsObject)
                {
                    if (seqDistance <= -UdpSocket.AckRedundancy)
                    {
                        // track stats
                        stats.PacketLost();
                        socket.Statistics.PacketLost();

                        // handle lost
                        ObjectLost(handle.Object);
                    }
                    else
                    {
                        if ((header.AckHistory & (1UL << -seqDistance)) != 0UL)
                        {
                            // track stats
                            stats.PacketDelivered();
                            socket.Statistics.PacketDelivered();

                            // handle delivered objects
                            ObjectDelivered(handle.Object);
                        }
                        else
                        {
                            // track stats
                            stats.PacketLost();
                            socket.Statistics.PacketLost();

                            // handle
                            ObjectLost(handle.Object);
                        }
                    }
                }

                if (seqDistance == 0 && header.AckTime > 0)
                {
                    UpdatePing(recvTime, handle.SendTime, header.AckTime);
                }

                sendWindow.Dequeue();
            }
        }
Esempio n. 5
0
        internal void SendObject(object o)
        {
            serializer.SendNext(o);

            while (serializer.HasQueuedObjects)
            {
                UdpSendFailReason reason = CheckCanSend(false);

                if (reason != UdpSendFailReason.None)
                {
                    while (serializer.HasQueuedObjects)
                    {
                        socket.Raise(UdpEvent.PUBLIC_OBJECT_SEND_FAILED, this, serializer.NextObject(), reason);
                    }

                    break;
                }

                UdpBitStream stream = new UdpBitStream(socket.GetWriteBuffer(), mtu, UdpHeader.GetSize(socket));
                object       obj    = serializer.NextObject();

                if (serializer.Pack(ref stream, ref obj))
                {
                    if (stream.Overflowing && (socket.Config.AllowPacketOverflow == false))
                    {
                        UdpLog.Error("stream to {0} is overflowing, not sending", endpoint.ToString());
                        socket.Raise(UdpEvent.PUBLIC_OBJECT_SEND_FAILED, this, obj, UdpSendFailReason.StreamOverflow);
                        return;
                    }

                    UdpHeader header = MakeHeader(true);
                    header.Pack(new UdpBitStream(stream.Data, mtu, 0), socket);

                    UdpHandle handle = MakeHandle(ref header);
                    handle.Object = obj;

                    if (SendStream(stream, handle, alwaysSendMtu) == false)
                    {
                        socket.Raise(UdpEvent.PUBLIC_OBJECT_SEND_FAILED, this, obj, UdpSendFailReason.SocketError);
                    }
                    else
                    {
                        stats.PacketSent();
                    }
                }
                else
                {
                    socket.Raise(UdpEvent.PUBLIC_OBJECT_SEND_FAILED, this, obj, UdpSendFailReason.SerializerReturnedFalse);
                }
            }
        }
Esempio n. 6
0
        bool SendStream(UdpStream stream, UdpHandle handle, bool expandToMtu)
        {
            int bytesToSend = UdpMath.BytesRequired(stream.Ptr);

            if (bytesToSend < mtu && expandToMtu)
            {
                bytesToSend = mtu;
            }

            sendTime     = handle.SendTime;
            sendSequence = handle.ObjSequence;
            sendWindow.Enqueue(handle);
            recvSinceLastSend = 0;

            return(socket.Send(endpoint, stream.Data, bytesToSend));
        }
Esempio n. 7
0
        void OnStateDisconnected(UdpConnectionState oldState)
        {
            if (oldState == UdpConnectionState.Connected)
            {
                while (sendWindow.Empty == false)
                {
                    UdpHandle handle = sendWindow.Dequeue();

                    if (handle.IsObject)
                    {
                        socket.Raise(UdpEvent.PUBLIC_OBJECT_LOST, this, handle.Object);
                    }
                }

                socket.Raise(UdpEvent.PUBLIC_DISCONNECTED, this);
            }
        }
Esempio n. 8
0
        internal void SendCommand(UdpCommandType cmd)
        {
            if (CheckCanSend(true) == UdpSendFailReason.None)
            {
                UdpBitStream stream = new UdpBitStream(socket.GetWriteBuffer(), mtu, UdpHeader.GetSize(socket));
                stream.WriteByte((byte)cmd, 8);

                UdpHeader header = MakeHeader(false);
                header.Pack(new UdpBitStream(stream.Data, mtu, 0), socket);

                UdpHandle handle = MakeHandle(ref header);
                handle.Object = null;

                if (SendStream(stream, handle, false) == false)
                {
                    // do something here?
                }

                stats.CommandSent += 1;
            }
        }
Esempio n. 9
0
        void AckHandles(UdpHeader header, bool updateRtt)
        {
            while (!sendWindow.Empty)
            {
                UdpHandle handle = sendWindow.Peek();

                int seqDistance = UdpMath.SeqDistance(handle.ObjSequence, header.AckSequence, UdpHeader.SEQ_PADD);
                if (seqDistance > 0)
                {
                    break;
                }

                if (handle.IsObject)
                {
                    if (seqDistance <= -socket.Config.AckRedundancy)
                    {
                        ObjectLost(handle.Object);
                    }

                    if ((header.AckHistory & (1UL << -seqDistance)) != 0UL)
                    {
                        ObjectDelivered(handle.Object);
                    }
                    else
                    {
                        ObjectLost(handle.Object);
                    }
                }

                if (seqDistance == 0 && header.AckTime > 0)
                {
                    UpdatePing(recvTime, handle.SendTime, header.AckTime);
                }

                sendWindow.Dequeue();
            }
        }
Esempio n. 10
0
        bool SendStream(UdpBitStream stream, UdpHandle handle, bool expandToMtu)
        {
            int bytesToSend = UdpMath.BytesRequired(stream.Ptr);
            if (bytesToSend < mtu && expandToMtu) {
                bytesToSend = mtu;
            }

            sendTime = handle.SendTime;
            sendSequence = handle.ObjSequence;
            sendWindow.Enqueue(handle);
            recvSinceLastSend = 0;

            return socket.Send(endpoint, stream.Data, bytesToSend);
        }
Esempio n. 11
0
 UdpHandle MakeHandle(ref UdpHeader header)
 {
     UdpHandle handle = new UdpHandle();
     handle.IsObject = header.IsObject;
     handle.ObjSequence = header.ObjSequence;
     handle.SendTime = header.Now;
     return handle;
 }