public ReliableChannel(NetPeer peer, bool ordered) { _windowSize = NetConstants.DefaultWindowSize; _peer = peer; _ordered = ordered; _outgoingPackets = new Queue <NetPacket>(_windowSize); _pendingPackets = new PendingPacket[_windowSize]; for (int i = 0; i < _pendingPackets.Length; i++) { _pendingPackets[i] = new PendingPacket(); } if (_ordered) { _receivedPackets = new NetPacket[_windowSize]; } else { _earlyReceived = new bool[_windowSize]; } _localWindowStart = 0; _localSeqence = 0; _remoteSequence = 0; _remoteWindowStart = 0; //Init acks packet int bytesCount = (_windowSize - 1) / BitsInByte + 1; PacketProperty property = _ordered ? PacketProperty.AckReliableOrdered : PacketProperty.AckReliable; _outgoingAcks = _peer.GetPacketFromPool(property, bytesCount); }
private void CreateAndSend(PacketProperty property, ushort sequence) { NetPacket packet = _packetPool.Get(property, 0); packet.Sequence = sequence; SendPacket(packet); }
public NetPacket GetWithData(PacketProperty property, int channel, byte[] data, int start, int length) { var packet = Get(property, channel, length); Buffer.BlockCopy(data, start, packet.RawData, 0, length); return(packet); }
public static int GetHeaderSize(PacketProperty property) { switch (property) { case PacketProperty.Channeled: case PacketProperty.Ack: return(NetConstants.ChanneledHeaderSize); case PacketProperty.Ping: return(NetConstants.HeaderSize + 2); case PacketProperty.ConnectRequest: return(NetConnectRequestPacket.HeaderSize); case PacketProperty.ConnectAccept: return(NetConnectAcceptPacket.Size); case PacketProperty.Disconnect: return(NetConstants.HeaderSize + 8); case PacketProperty.Pong: return(NetConstants.HeaderSize + 10); default: return(NetConstants.HeaderSize); } }
public NetPacket(PacketProperty property, int size) { size += GetHeaderSize(property); RawData = new byte[size]; Property = property; Size = size; }
/// <summary> /// 데이터를 전송함 /// </summary> /// <param name="data">보낼 데이터 버퍼</param> /// <param name="offset">보낼 데이터 버퍼 오프셋</param> /// <param name="length">보낼 데이터 길이</param> /// <param name="deliveryMethod">전송 방법</param> public void SendAsync(byte[] data, int offset, int length, DeliveryMethod deliveryMethod) { if (State != SessionState.Connected) { return; } IChannel channel = GetChannel(deliveryMethod); if (channel == null) { throw new Exception($"can not found channel : {deliveryMethod}"); } PacketProperty property = PacketProperty.UserData; int headerSize = NetPacket.GetHeaderSize(property); NetPacket packet = NetPool.PacketPool.Alloc(headerSize + length); packet.Property = property; packet.DeliveryMethod = deliveryMethod; Buffer.BlockCopy(data, offset, packet.RawData, headerSize, length); channel.SendAsync(packet); }
public NetPacket GetWithProperty(PacketProperty property) { NetPacket packet = GetPacket(NetPacket.GetHeaderSize(property)); packet.Property = property; return(packet); }
public NetPacket GetWithData(PacketProperty property, int channel, NetDataWriter writer) { var packet = Get(property, writer.Length, channel); Buffer.BlockCopy(writer.Data, 0, packet.RawData, 0, writer.Length); return(packet); }
public void Init(PacketProperty property, NetDataWriter dataWriter) { int headerSize = GetHeaderSize(property); RawData = new byte[headerSize + dataWriter.Length]; Property = property; Buffer.BlockCopy(dataWriter.Data, 0, RawData, headerSize, dataWriter.Length); }
//Get packet with size public NetPacket GetWithProperty(PacketProperty property, int size) { size += NetPacket.GetHeaderSize(property); NetPacket packet = GetPacket(size, true); packet.Property = property; return(packet); }
public NetPacket GetWithData(PacketProperty property, byte[] data, int start, int length) { int headerSize = NetPacket.GetHeaderSize(property); NetPacket packet = GetPacket(length + headerSize); packet.Property = property; Buffer.BlockCopy(data, start, packet.RawData, headerSize, length); return(packet); }
public static byte[] CreateRawPacket(PacketProperty property, byte[] data, int start, int count) { int headerSize = GetHeaderSize(property); byte[] rawData = new byte[headerSize + count]; rawData[0] = (byte)property; Buffer.BlockCopy(data, start, rawData, headerSize, count); return(rawData); }
public static byte[] CreateRawPacket(PacketProperty property, NetDataWriter dataWriter) { int headerSize = GetHeaderSize(property); byte[] rawData = new byte[headerSize + dataWriter.Length]; rawData[0] = (byte)property; Buffer.BlockCopy(dataWriter.Data, 0, rawData, headerSize, dataWriter.Length); return(rawData); }
public static bool ComparePacketProperty(byte[] data, PacketProperty check) { PacketProperty property; if (GetPacketProperty(data, out property)) { return(property == check); } return(false); }
public static bool IsSequenced(PacketProperty property) { return(property == PacketProperty.ReliableOrdered || property == PacketProperty.Reliable || property == PacketProperty.Sequenced || property == PacketProperty.Ping || property == PacketProperty.Pong || property == PacketProperty.AckReliable || property == PacketProperty.AckReliableOrdered); }
//Get packet with size public NetPacket Get(PacketProperty property, int channel, int size) { size += NetPacket.GetHeaderSize(property); NetPacket packet = GetPacket(size, true); packet.Channel = channel; packet.Size = size; packet.Property = property; return(packet); }
public void Send(byte[] data, int start, int length, SendOptions options) { //Prepare PacketProperty property = SendOptionsToProperty(options); int headerSize = NetPacket.GetHeaderSize(property); //Check fragmentation if (length + headerSize > _mtu) { //TODO: fix later if (options == SendOptions.Sequenced || options == SendOptions.Unreliable) { throw new Exception("Unreliable packet size > allowed (" + (_mtu - headerSize) + ")"); } int packetFullSize = _mtu - headerSize; int packetDataSize = packetFullSize - NetConstants.FragmentHeaderSize; int fullPacketsCount = length / packetDataSize; int lastPacketSize = length % packetDataSize; int totalPackets = fullPacketsCount + (lastPacketSize == 0 ? 0 : 1); for (int i = 0; i < fullPacketsCount; i++) { NetPacket p = GetPacketFromPool(property, packetFullSize); p.FragmentId = _fragmentId; p.FragmentPart = (uint)i; p.FragmentsTotal = (uint)totalPackets; p.IsFragmented = true; p.PutData(data, i * packetDataSize, packetDataSize); SendPacket(p); } if (lastPacketSize > 0) { NetPacket p = GetPacketFromPool(property, lastPacketSize + NetConstants.FragmentHeaderSize); p.FragmentId = _fragmentId; p.FragmentPart = (uint)fullPacketsCount; //last p.FragmentsTotal = (uint)totalPackets; p.IsFragmented = true; p.PutData(data, fullPacketsCount * packetDataSize, lastPacketSize); SendPacket(p); } _fragmentId++; return; } //Else just send NetPacket packet = GetPacketFromPool(property, length); packet.PutData(data, start, length); SendPacket(packet); }
public static bool GetPacketProperty(byte[] data, out PacketProperty property) { byte properyByte = (byte)(data[0] & 0x7F); if (properyByte > LastProperty) { property = PacketProperty.None; return(false); } property = (PacketProperty)properyByte; return(true); }
public void SendAsync(byte[] data, int offset, int length, DeliveryMethod deliveryMethod) { PacketProperty property = PacketProperty.UserData; int headerSize = NetPacket.GetHeaderSize(property); NetPacket packet = NetPool.PacketPool.Alloc(headerSize + length); packet.Property = property; packet.DeliveryMethod = deliveryMethod; Buffer.BlockCopy(data, offset, packet.RawData, headerSize, length); UdpChannel.SendAsync(packet); }
private static bool CanMerge(PacketProperty property) { switch (property) { case PacketProperty.ConnectAccept: case PacketProperty.ConnectRequest: case PacketProperty.Pong: case PacketProperty.Disconnect: return(false); default: return(true); } }
public void SendAcks() { if (!_mustSendAcks) { return; } _mustSendAcks = false; NetUtils.DebugWrite("[RR]SendAcks"); //Init packet int bytesCount = (_windowSize - 1) / BitsInByte + 1; PacketProperty property = _ordered ? PacketProperty.AckReliableOrdered : PacketProperty.AckReliable; var acksPacket = _peer.GetPacketFromPool(property, bytesCount); //For quick access byte[] data = acksPacket.RawData; //window start + acks size //Put window start Monitor.Enter(_outgoingAcks); acksPacket.Sequence = (ushort)_remoteWindowStart; //Put acks int startAckIndex = _remoteWindowStart % _windowSize; int currentAckIndex = startAckIndex; int currentBit = 0; int currentByte = NetConstants.SequencedHeaderSize; do { if (_outgoingAcks[currentAckIndex]) { data[currentByte] |= (byte)(1 << currentBit); } currentBit++; if (currentBit == BitsInByte) { currentByte++; currentBit = 0; } currentAckIndex = (currentAckIndex + 1) % _windowSize; } while (currentAckIndex != startAckIndex); Monitor.Exit(_outgoingAcks); _peer.SendRawData(acksPacket); _peer.Recycle(acksPacket); }
public static int GetHeaderSize(PacketProperty property) { switch (property) { case PacketProperty.ReliableOrdered: case PacketProperty.Reliable: case PacketProperty.Sequenced: case PacketProperty.Ping: case PacketProperty.Pong: case PacketProperty.AckReliable: case PacketProperty.AckReliableOrdered: return(NetConstants.SequencedHeaderSize); default: return(NetConstants.HeaderSize); } }
private void SendAcks(bool aboutToSendData, long currentTime) { // Try to send acks with data or after end of time if (_mustSendAcksStartTimer > 0) { long elapsedTime = currentTime - _mustSendAcksStartTimer; if (aboutToSendData == true || elapsedTime >= (long)(0.5f * (float)_peer.AvgRtt * 1.1f)) { _mustSendAcksStartTimer = -1; NetUtils.DebugWrite("[RR]SendAcks"); // Build outgoingAcks packet if (_packetsToAcknowledge.Count > 0) { //Init acks packet PacketProperty property = _ordered ? PacketProperty.AckReliableOrdered : PacketProperty.AckReliable; NetPacket _outgoingAcks = _peer.GetPacketFromPool(property, _channel, NetConstants.MinPacketDataSize); int diff = RelativeSequenceDiff(_packetsToAcknowledgeMax, _packetsToAcknowledgeMin); _outgoingAcks.Size = NetConstants.SequencedHeaderSize + diff / 8 + 1; _outgoingAcks.Property = _ordered ? PacketProperty.AckReliableOrdered : PacketProperty.AckReliable; _outgoingAcks.Channel = _channel; _outgoingAcks.Sequence = _packetsToAcknowledgeMin; // Set all to 0 Array.Clear(_outgoingAcks.RawData, 0, _outgoingAcks.Size - NetConstants.SequencedHeaderSize); // Set bit to 1 foreach packet to ack int ackIdx, ackByte, ackBit; foreach (ushort seq in _packetsToAcknowledge) { ackIdx = RelativeSequenceDiff(seq, _outgoingAcks.Sequence); ackByte = ackIdx / BitsInByte; ackBit = ackIdx % BitsInByte; _outgoingAcks.RawData[ackByte] |= (byte)(1 << ackBit); } _packetsToAcknowledge.Clear(); //Monitor.Enter(_outgoingAcks); _peer.SendRawData(_outgoingAcks); //Monitor.Exit(_outgoingAcks); } } } }
internal NetPacket GetPacketFromPool(PacketProperty property = PacketProperty.Unreliable, int size = 0, bool init = true) { NetPacket packet = null; lock (_packetPool) { if (_packetPool.Count > 0) { packet = _packetPool.Pop(); } } if (packet == null) { packet = new NetPacket(); } if (init) { packet.Init(property, size); } return(packet); }
internal void ProcessMessage(NetEndPoint senderEndPoint, PacketProperty property, byte[] data) { NetDataReader dr = new NetDataReader(data); switch (property) { case PacketProperty.NatIntroductionRequest: //We got request and must introduce HandleNatIntroductionRequest(senderEndPoint, dr); break; case PacketProperty.NatIntroduction: //We got introduce and must punch HandleNatIntroduction(dr); break; case PacketProperty.NatPunchMessage: //We got punch and can connect HandleNatPunch(senderEndPoint, dr); break; } }
public static int GetHeaderSize(PacketProperty property) { switch (property) { case PacketProperty.UserData: case PacketProperty.Request: case PacketProperty.ViewRequest: case PacketProperty.Ack: return(UserDataHeaderSize); case PacketProperty.RequestConnection: case PacketProperty.ResponseConnection: return(HeaderSize + 2); case PacketProperty.MtuOk: return(HeaderSize + 1); case PacketProperty.Ping: return(HeaderSize + 2); case PacketProperty.Pong: return(HeaderSize + 10); case PacketProperty.JoinP2p: case PacketProperty.LeaveP2p: case PacketProperty.HolePunchingStart: case PacketProperty.HolePunchingEnd: return(UserDataHeaderSize); case PacketProperty.AliveCheck: return(HeaderSize + 1); default: return(HeaderSize); } }
public static bool GetPacketProperty(byte[] data, out PacketProperty property) { byte properyByte = (byte)(data[0] & 0x7F); if (properyByte > LastProperty) { property = PacketProperty.Unreliable; return false; } property = (PacketProperty)properyByte; return true; }
internal void CreateAndSend(PacketProperty property) { NetPacket packet = GetPacketFromPool(property); SendPacket(packet); }
public static byte[] CreateRawPacket(PacketProperty property, NetDataWriter dataWriter) { int headerSize = GetHeaderSize(property); byte[] rawData = new byte[headerSize + dataWriter.Length]; rawData[0] = (byte)property; Buffer.BlockCopy(dataWriter.Data, 0, rawData, headerSize, dataWriter.Length); return rawData; }
public static byte[] CreateRawPacket(PacketProperty property, byte[] data, int start, int count) { int headerSize = GetHeaderSize(property); byte[] rawData = new byte[headerSize + count]; rawData[0] = (byte)property; Buffer.BlockCopy(data, start, rawData, headerSize, count); return rawData; }
//Always not fragmented public static byte[] CreateRawPacket(PacketProperty property, int dataSize) { byte[] rawData = new byte[GetHeaderSize(property) + dataSize]; rawData[0] = (byte) property; return rawData; }
//Packet constructor public void Init(PacketProperty property, int dataSize) { RawData = new byte[GetHeaderSize(property) + dataSize]; Property = property; }
private void CreateAndSend(PacketProperty property, ushort sequence) { NetPacket packet = GetPacketFromPool(property); packet.Sequence = sequence; SendPacket(packet); }
set => SetValue(PacketProperty, value);
internal void OnReceivedRawUdpData(byte[] data, int size, NetPacket cachedPacket, SocketError error, IPEndPoint endPoint) { //Console.WriteLine($"buffer size : {size} packet size : {BitConverter.ToUInt16(data, 0)}"); if (size < NetPacket.HeaderSize) return; try { PacketProperty property = cachedPacket.Property; DeliveryMethod deliveryMethod = cachedPacket.DeliveryMethod; switch (property) { case PacketProperty.MtuCheck: { NetPacket packet = NetPool.PacketPool.Alloc(NetPacket.GetHeaderSize(PacketProperty.MtuOk)); try { byte getMtuId = data[3]; packet.Property = PacketProperty.MtuOk; packet.DeliveryMethod = DeliveryMethod.Unreliable; packet.RawData[3] = getMtuId; SendTo(packet.RawData, 0, packet.Size, SendMode.Immediately); } catch (Exception ex) { _logger.LogError(ex, "Exception happened in MtuCheck"); } finally { NetPool.PacketPool.Free(packet); } } break; case PacketProperty.MtuOk: { try { byte getMtuId = data[3]; if (getMtuId >= _mtuId) { _mtuId = getMtuId; _mtu = NetPacket.PossibleMtu[getMtuId]; if (_mtuId >= NetPacket.PossibleMtu.Length) _finishMtu = true; //Console.WriteLine($"SetMtu : {_mtu}"); } } catch (Exception ex) { _logger.LogError(ex, "Exception happened in MtuOk"); } } break; case PacketProperty.Ping: { ushort sequence = BitConverter.ToUInt16(data, 3); if (NetUtil.RelativeSequenceNumber(sequence, _pongPacket.Sequence) > 0) { FastBitConverter.GetBytes(_pongPacket.RawData, 5, DateTime.UtcNow.Ticks); _pongPacket.Sequence = sequence; SendTo(_pongPacket.RawData, 0, _pongPacket.Size, SendMode.Immediately); } } break; case PacketProperty.Pong: { ushort sequence = BitConverter.ToUInt16(data, 3); if (sequence == _pingPacket.Sequence) { _pingTimer.Stop(); int elapsedMs = (int)_pingTimer.ElapsedMilliseconds; _remoteTickDelta = BitConverter.ToInt64(data, 5) + (elapsedMs * TimeSpan.TicksPerMillisecond) / 2 - DateTime.UtcNow.Ticks; UpdateRoundTripTime(elapsedMs); //Console.WriteLine($"Pong sequence : {sequence} {elapsedMs} ms {_remoteTickDelta} microseconds"); } } break; default: { ReadPacket(data, size, _channelOption.PacketFilter); } break; } } catch (Exception e) { _logger.LogError(e, "Exception happened in OnReceivedRawUdpData"); Close(); } }
public static bool ComparePacketProperty(byte[] data, PacketProperty check) { PacketProperty property; if (GetPacketProperty(data, out property)) { return property == check; } return false; }
public void Send(byte[] data, int start, int length, SendOptions options) { //Prepare PacketProperty property = SendOptionsToProperty(options); int headerSize = NetPacket.GetHeaderSize(property); //Check fragmentation if (length + headerSize > _mtu) { if (options == SendOptions.Sequenced || options == SendOptions.Unreliable) { throw new Exception("Unreliable packet size > allowed (" + (_mtu - headerSize) + ")"); } int packetFullSize = _mtu - headerSize; int packetDataSize = packetFullSize - NetConstants.FragmentHeaderSize; int fullPacketsCount = length / packetDataSize; int lastPacketSize = length % packetDataSize; int totalPackets = fullPacketsCount + (lastPacketSize == 0 ? 0 : 1); DebugWrite("MTU: {0}, HDR: {1}, PFS: {2}, PDS: {3}, FPC: {4}, LPS: {5}, TP: {6}", _mtu, headerSize, packetFullSize, packetDataSize, fullPacketsCount, lastPacketSize, totalPackets); if (totalPackets > ushort.MaxValue) { throw new Exception("Too many fragments: " + totalPackets + " > " + ushort.MaxValue); } for (ushort i = 0; i < fullPacketsCount; i++) { NetPacket p = GetPacketFromPool(property, packetFullSize); p.FragmentId = _fragmentId; p.FragmentPart = i; p.FragmentsTotal = (ushort)totalPackets; p.IsFragmented = true; p.PutData(data, i * packetDataSize, packetDataSize); SendPacket(p); } if (lastPacketSize > 0) { NetPacket p = GetPacketFromPool(property, lastPacketSize + NetConstants.FragmentHeaderSize); p.FragmentId = _fragmentId; p.FragmentPart = (ushort)fullPacketsCount; //last p.FragmentsTotal = (ushort)totalPackets; p.IsFragmented = true; p.PutData(data, fullPacketsCount * packetDataSize, lastPacketSize); SendPacket(p); } _fragmentId++; return; } //Else just send NetPacket packet = GetPacketFromPool(property, length); packet.PutData(data, start, length); SendPacket(packet); }
public static int GetHeaderSize(PacketProperty property) { return IsSequenced(property) ? NetConstants.SequencedHeaderSize : NetConstants.HeaderSize; }
public static bool IsSequenced(PacketProperty property) { return property == PacketProperty.ReliableOrdered || property == PacketProperty.Reliable || property == PacketProperty.Sequenced || property == PacketProperty.Ping || property == PacketProperty.Pong || property == PacketProperty.AckReliable || property == PacketProperty.AckReliableOrdered; }
internal NetPacket GetPacketFromPool(PacketProperty property = PacketProperty.Unreliable, int size=0, bool init=true) { NetPacket packet = null; lock (_packetPool) { if (_packetPool.Count > 0) { packet = _packetPool.Pop(); } } if(packet == null) { packet = new NetPacket(); } if(init) packet.Init(property, size); return packet; }