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()); } } }
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); }
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()); } }
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()); } }
/// <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); }
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); }
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)); }
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()); } } }
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); }
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()); } } }
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); } } }
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); } }
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); } } }
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); }
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); }
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); }
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); }
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); }
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); } } }
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))); } }
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); } }
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); }
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); } }
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); }
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))); }
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); }
public static void SetWriter(UdpLog.Writer callback) { writer = callback; }