示例#1
0
        void NetworkLoop()
        {
            while (true)
            {
                try {
                    UdpLog.Info("socket created");
                    while (state == udpSocketState.Created)
                    {
                        ProcessIncommingEvents(true);
                        Thread.Sleep(1);
                    }

                    UdpLog.Info("socket started");
                    while (state == udpSocketState.Running)
                    {
                        RecvDelayedPackets();
                        RecvNetworkData();
                        ProcessTimeouts();
                        ProcessIncommingEvents(false);
                        frame += 1;
                    }

                    UdpLog.Info("socket closed");
                } catch (Exception exn) {
                    UdpLog.Error(exn.ToString());
                }
            }
        }
示例#2
0
        void RecvNetworkData()
        {
            if (platform.RecvPoll(1))
            {
                int         byteReceived = 0;
                UdpEndPoint ep           = UdpEndPoint.Any;

                if (platform.RecvFrom(receiveBuffer, receiveBuffer.Length, ref byteReceived, ref ep))
                {
#if DEBUG
                    if (random.NextDouble() < Config.SimulatedLoss)
                    {
                        UdpLog.Info("simulated loss of packet from {0}", ep.ToString());
                        return;
                    }
#endif
                    UdpConnection cn;

                    if (connLookup.TryGetValue(ep, out cn))
                    {
                        cn.OnPacket(new UdpBitStream(receiveBuffer, byteReceived));
                    }
                    else
                    {
                        RecvUnconnectedPacket(new UdpBitStream(receiveBuffer, byteReceived), ep);
                    }
                }
            }
        }
        public void WriteByteArray(byte[] from, int offset, int count)
        {
#if TRACE_RW
            if (UdpLog.IsEnabled(UdpLog.TRACE))
            {
                UdpLog.Trace("Writing byte array ({0} bits)", count * 8);
            }
#endif
            int p        = Ptr >> 3;
            int bitsUsed = Ptr % 8;
            int bitsFree = 8 - bitsUsed;

            if (bitsUsed == 0)
            {
                Buffer.BlockCopy(from, offset, Data, p, count);
            }
            else
            {
                for (int i = 0; i < count; ++i)
                {
                    byte value = from[offset + i];

                    Data[p] &= (byte)(0xFF >> bitsFree);
                    Data[p] |= (byte)(value << bitsUsed);

                    p += 1;

                    Data[p] &= (byte)(0xFF << bitsUsed);
                    Data[p] |= (byte)(value >> bitsFree);
                }
            }

            Ptr += (count * 8);
        }
        public void ReadByteArray(byte[] to, int offset, int count)
        {
#if TRACE_RW
            if (UdpLog.IsEnabled(UdpLog.TRACE))
            {
                UdpLog.Trace("Reading byte array ({0} bits)", count * 8);
            }
#endif

            int p        = Ptr >> 3;
            int bitsUsed = Ptr % 8;

            if (bitsUsed == 0)
            {
                Buffer.BlockCopy(Data, p, to, offset, count);
            }
            else
            {
                int bitsNotUsed = 8 - bitsUsed;

                for (int i = 0; i < count; ++i)
                {
                    int first = Data[p] >> bitsUsed;

                    p += 1;

                    int second = Data[p] & (255 >> bitsNotUsed);
                    to[offset + i] = (byte)(first | (second << bitsNotUsed));
                }
            }

            Ptr += (count * 8);
        }
示例#5
0
        void RecvUnconnectedPacket(UdpBitStream buff, UdpEndPoint ep)
        {
            buff.Ptr = UdpHeader.GetSize(this);

            if (buff.ReadByte(8) == (byte)UdpCommandType.Connect)
            {
                if (Config.AllowIncommingConnections && ((connLookup.Count + pendingConnections.Count) < Config.ConnectionLimit || Config.ConnectionLimit == -1))
                {
                    if (Config.AutoAcceptIncommingConnections)
                    {
                        AcceptConnection(ep);
                    }
                    else
                    {
                        if (pendingConnections.Add(ep))
                        {
                            Raise(UdpEvent.PUBLIC_CONNECT_REQUEST, ep);
                        }
                    }
                }
                else
                {
                    SendRefusedCommand(ep);
                }
            }
            else
            {
                UdpLog.Debug("received invalid header byte in unconnected packet from {0}", ep.ToString());
            }
        }
示例#6
0
        void OnEventClose(UdpEvent ev)
        {
            if (ChangeState(UdpSocketState.Running, UdpSocketState.Shutdown))
            {
                for (int i = 0; i < connList.Count; ++i)
                {
                    UdpConnection cn = connList[i];
                    cn.SendCommand(UdpCommandType.Disconnected);
                    cn.ChangeState(UdpConnectionState.Disconnected);
                }

                if (platform.Close() == false)
                {
                    UdpLog.Error("failed to shutdown socket interface, platform code: {0}", platform.PlatformError.ToString());
                }

                connList.Clear();
                connLookup.Clear();
                eventQueueIn.Clear();
                pendingConnections.Clear();

                GetReadStream().Data      = null;
                GetWriteStream(0, 0).Data = null;
                UdpLog.Error("OnEventClose: {0}", ev.EndPoint.ToString());
            }
        }
示例#7
0
        /// <summary>
        /// Suspends the networking thread for N milliseconds.
        /// Usefull for simulating unusual networking conditions.
        /// </summary>
        /// <param name="milliseconds">How long to sleep</param>
        public void Sleep(int milliseconds)
        {
#if DEBUG
            Raise(UdpEvent.INTERNAL_SLEEP, milliseconds);
#else
            UdpLog.Warn("Calling UdpSocket.Sleep in non-debug build is not supported");
#endif
        }
        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);
                }
            }
        }
        public bool ReadBool()
        {
#if TRACE_RW
            if (UdpLog.IsEnabled(UdpLog.TRACE))
            {
                UdpLog.Trace("Reading bool (1 bit)");
            }
#endif
            return(InternalReadByte(1) == 1);
        }
示例#10
0
        public void WriteSByte(sbyte value, int bits)
        {
#if TRACE_RW
            if (UdpLog.IsEnabled(UdpLog.TRACE))
            {
                UdpLog.Trace("Writing sbyte ({0} bits)", bits);
            }
#endif
            InternalWriteByte((byte)value, bits);
        }
示例#11
0
        public sbyte ReadSByte(int bits)
        {
#if TRACE_RW
            if (UdpLog.IsEnabled(UdpLog.TRACE))
            {
                UdpLog.Trace("Reading sbyte ({0} bits)", bits);
            }
#endif
            return((sbyte)InternalReadByte(bits));
        }
示例#12
0
 void OnEventClose(UdpEvent ev)
 {
     if (ChangeState(udpSocketState.Running, udpSocketState.Shutdown))
     {
         if (platform.Close() == false)
         {
             UdpLog.Error("failed to shutdown socket interface, platform code: {0}", platform.PlatformError.ToString());
         }
     }
 }
示例#13
0
        public bool WriteBool(bool value)
        {
#if TRACE_RW
            if (UdpLog.IsEnabled(UdpLog.TRACE))
            {
                UdpLog.Trace("Writing bool (1 bit)");
            }
#endif
            InternalWriteByte(value ? (byte)1 : (byte)0, 1);
            return(value);
        }
示例#14
0
        void OnEventConnect(UdpEvent ev)
        {
            if (CheckState(udpSocketState.Running))
            {
                UdpConnection cn = CreateConnection(ev.EndPoint, UdpConnectionMode.Client);

                if (cn == null)
                {
                    UdpLog.Error("could not create connection for endpoint {0}", ev.EndPoint.ToString());
                }
            }
        }
示例#15
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);
                }
            }
        }
示例#16
0
        void OnStateConnected(UdpConnectionState oldState)
        {
            if (oldState == UdpConnectionState.Connecting)
            {
                UdpLog.Info("connected to {0}", endpoint.ToString());

                if (IsServer)
                {
                    SendCommand(UdpCommandType.Accepted);
                }

                socket.Raise(UdpEvent.PUBLIC_CONNECTED, this);
            }
        }
示例#17
0
 void OnEventStart(UdpEvent ev)
 {
     if (ChangeState(udpSocketState.Created, udpSocketState.Running))
     {
         if (platform.Bind(ev.EndPoint))
         {
             UdpLog.Info("socket bound to {0}", platform.EndPoint.ToString());
         }
         else
         {
             UdpLog.Error("could not bind socket, platform code: {0}, platform error: {1}", platform.PlatformError.ToString(), platform.PlatformErrorString);
         }
     }
 }
示例#18
0
        public void WriteFloat(float value)
        {
#if TRACE_RW
            if (UdpLog.IsEnabled(UdpLog.TRACE))
            {
                UdpLog.Trace("Writing float (32 bits)");
            }
#endif
            UdpByteConverter bytes = value;
            InternalWriteByte(bytes.Byte0, 8);
            InternalWriteByte(bytes.Byte1, 8);
            InternalWriteByte(bytes.Byte2, 8);
            InternalWriteByte(bytes.Byte3, 8);
        }
示例#19
0
        public bool WriteBool(bool value)
        {
#if TRACE_RW
            if (UdpLog.IsEnabled(UdpLog.TRACE))
            {
                UdpLog.Trace("Writing bool (1 bit)");
            }
#endif
            //Core.net.bitsOut += 1;
            Core.net.AddToBandwidthOutBuffer(1);
            //UnityEngine.Debug.Log("Write Bool (1 bit");
            InternalWriteByte(value ? (byte)1 : (byte)0, 1);
            return(value);
        }
示例#20
0
        public bool ReadBool()
        {
#if TRACE_RW
            if (UdpLog.IsEnabled(UdpLog.TRACE))
            {
                UdpLog.Trace("Reading bool (1 bit)");
            }
#endif
            //Core.net.bitsIn += 1;
            Core.net.AddToBandwidthInBuffer(1);

            //UnityEngine.Debug.Log("Read Bool (1 bit");
            return(InternalReadByte(1) == 1);
        }
示例#21
0
        UdpConnection CreateConnection(UdpEndPoint endpoint, UdpConnectionMode mode)
        {
            if (connLookup.ContainsKey(endpoint))
            {
                UdpLog.Warn("connection for {0} already exists", endpoint);
                return(default(UdpConnection));
            }

            UdpConnection cn = new UdpConnection(this, mode, endpoint);

            connLookup.Add(endpoint, cn);
            connList.Add(cn);

            return(cn);
        }
示例#22
0
        public float ReadFloat()
        {
#if TRACE_RW
            if (UdpLog.IsEnabled(UdpLog.TRACE))
            {
                UdpLog.Trace("Reading float (32 bits)");
            }
#endif
            UdpByteConverter bytes = default(UdpByteConverter);
            bytes.Byte0 = InternalReadByte(8);
            bytes.Byte1 = InternalReadByte(8);
            bytes.Byte2 = InternalReadByte(8);
            bytes.Byte3 = InternalReadByte(8);
            return(bytes.Float32);
        }
示例#23
0
        internal void ProcessConnectedTimeouts(uint now)
        {
            if ((recvTime + socket.Config.ConnectionTimeout) < now)
            {
                UdpLog.Debug("disconnecting due to timeout from {0}, last packet received: {1}, current time: {2}", endpoint.ToString(), recvTime.ToString(), now.ToString());
                ChangeState(UdpConnectionState.Disconnected);
            }

            if (CheckState(UdpConnectionState.Connected))
            {
                if (sendTime + socket.Config.PingTimeout < now || recvSinceLastSend >= socket.Config.RecvWithoutAckLimit)
                {
                    SendCommand(UdpCommandType.Ping);
                }
            }
        }
示例#24
0
        public ushort ReadUShort(int bits)
        {
#if TRACE_RW
            if (UdpLog.IsEnabled(UdpLog.TRACE))
            {
                UdpLog.Trace("Reading ushort ({0} bits)", bits);
            }
#endif
            if (bits <= 8)
            {
                return(InternalReadByte(bits));
            }
            else
            {
                return((ushort)(InternalReadByte(8) | (InternalReadByte(bits - 8) << 8)));
            }
        }
示例#25
0
        public void WriteUShort(ushort value, int bits)
        {
#if TRACE_RW
            if (UdpLog.IsEnabled(UdpLog.TRACE))
            {
                UdpLog.Trace("Writing ushort ({0} bits)", bits);
            }
#endif
            if (bits <= 8)
            {
                InternalWriteByte((byte)(value & 0xFF), bits);
            }
            else
            {
                InternalWriteByte((byte)(value & 0xFF), 8);
                InternalWriteByte((byte)(value >> 8), bits - 8);
            }
        }
示例#26
0
        public void WriteDouble(double value)
        {
#if TRACE_RW
            if (UdpLog.IsEnabled(UdpLog.TRACE))
            {
                UdpLog.Trace("Writing double (64 bits)");
            }
#endif
            UdpByteConverter bytes = value;
            InternalWriteByte(bytes.Byte0, 8);
            InternalWriteByte(bytes.Byte1, 8);
            InternalWriteByte(bytes.Byte2, 8);
            InternalWriteByte(bytes.Byte3, 8);
            InternalWriteByte(bytes.Byte4, 8);
            InternalWriteByte(bytes.Byte5, 8);
            InternalWriteByte(bytes.Byte6, 8);
            InternalWriteByte(bytes.Byte7, 8);
        }
示例#27
0
        public void WriteULong(ulong value, int bits)
        {
#if TRACE_RW
            if (UdpLog.IsEnabled(UdpLog.TRACE))
            {
                UdpLog.Trace("Writing ulong ({0} bits)", bits);
            }
#endif
            if (bits <= 32)
            {
                WriteUInt((uint)(value & 0xFFFFFFFF), bits);
            }
            else
            {
                WriteUInt((uint)(value), 32);
                WriteUInt((uint)(value >> 32), bits - 32);
            }
        }
示例#28
0
        bool SendConnectRequest()
        {
            if (connectAttempts < socket.Config.ConnectRequestAttempts)
            {
                if (connectAttempts != 0)
                {
                    UdpLog.Info("retrying connection to {0}", endpoint.ToString());
                }

                SendCommand(UdpCommandType.Connect);

                connectTimeout   = socket.GetCurrentTime() + socket.Config.ConnectRequestTimeout;
                connectAttempts += 1u;
                return(true);
            }

            return(false);
        }
示例#29
0
        public uint ReadUInt(int bits)
        {
#if TRACE_RW
            if (UdpLog.IsEnabled(UdpLog.TRACE))
            {
                UdpLog.Trace("Reading uint ({0} bits)", bits);
            }
#endif
            //UnityEngine.Debug.Log("Read Int (" + bits + " bits)");
            //Core.net.bitsIn += bits;
            Core.net.AddToBandwidthInBuffer(bits);
            int
                a = 0,
                b = 0,
                c = 0,
                d = 0;

            switch ((bits + 7) / 8)
            {
            case 1:
                a = InternalReadByte(bits);
                break;

            case 2:
                a = InternalReadByte(8);
                b = InternalReadByte(bits - 8);
                break;

            case 3:
                a = InternalReadByte(8);
                b = InternalReadByte(8);
                c = InternalReadByte(bits - 16);
                break;

            case 4:
                a = InternalReadByte(8);
                b = InternalReadByte(8);
                c = InternalReadByte(8);
                d = InternalReadByte(bits - 24);
                break;
            }

            return((uint)(a | (b << 8) | (c << 16) | (d << 24)));
        }
示例#30
0
        public double ReadDouble()
        {
#if TRACE_RW
            if (UdpLog.IsEnabled(UdpLog.TRACE))
            {
                UdpLog.Trace("Reading double (64 bits)");
            }
#endif
            UdpByteConverter bytes = default(UdpByteConverter);
            bytes.Byte0 = InternalReadByte(8);
            bytes.Byte1 = InternalReadByte(8);
            bytes.Byte2 = InternalReadByte(8);
            bytes.Byte3 = InternalReadByte(8);
            bytes.Byte4 = InternalReadByte(8);
            bytes.Byte5 = InternalReadByte(8);
            bytes.Byte6 = InternalReadByte(8);
            bytes.Byte7 = InternalReadByte(8);
            return(bytes.Float64);
        }
示例#31
0
 public static void SetWriter(UdpLog.Writer callback)
 {
     writer = callback;
 }