public void TestBase( IPacketFilter filter, int dataSize) { NetDataWriter writer = new NetDataWriter(); byte[] data = GetData(dataSize); foreach (var item in data) { writer.Write(item); } NetPacket packet = NetPool.PacketPool.Alloc(PacketProperty.UserData, writer); var encodedPacket = filter.Encode(packet); var decodedPacket = filter.Decode(encodedPacket); NetDataReader reader = new NetDataReader(decodedPacket); Assert.GreaterOrEqual(decodedPacket.Size, packet.Size); for (int i = 0; i < data.Length; i++) { Assert.AreEqual(data[i], reader.ReadByte()); } }
public override void SendAsync(NetPacket poolingPacket) { IPacketFilter filter = _channelOption.PacketFilter; while (filter != null) { poolingPacket = filter.Encode(poolingPacket); filter = filter.NextFilter; } Interlocked.Increment(ref _statistic.TcpPacketSentCount); lock (_sendedList) { if (_sendedList.Count > 0) { // 전송중임 _sendWaitQueue.Add(poolingPacket); return; } _sendedBufferList.Push(new ArraySegment <byte>(poolingPacket.RawData, 0, poolingPacket.Size)); _sendedList.Add(poolingPacket); } SendAsync(_sendedBufferList); }
public override void SendAsync(NetPacket poolingPacket) { var channel = GetChannel(poolingPacket.DeliveryMethod); if (channel == null) { NetPool.PacketPool.Free(poolingPacket); return; } int mtu = Mtu; if (poolingPacket.Size > mtu) { // 보낼수 있는 한계보다 큰 패킷이므로 쪼개서 보내자 Interlocked.Increment(ref _statistic.UdpFragmentCount); try { ushort currentFramentId = _fragments.GenerateId(); int headerSize = NetPacket.GetHeaderSize(poolingPacket.Property); int dataSize = poolingPacket.Size - headerSize; int maximumSize = mtu - headerSize; int maximumDataSize = maximumSize - NetPacket.FragmentHeaderSize; int totalPackets = dataSize / maximumDataSize + (dataSize % maximumDataSize == 0 ? 0 : 1); for (ushort partIdx = 0; partIdx < totalPackets; partIdx++) { int sendLength = dataSize > maximumDataSize ? maximumDataSize : dataSize; NetPacket p = NetPool.PacketPool.Alloc(sendLength + NetPacket.FragmentedHeaderTotalSize); p.Property = poolingPacket.Property; p.DeliveryMethod = poolingPacket.DeliveryMethod; p.P2pSessionId = poolingPacket.P2pSessionId; p.FragmentId = currentFramentId; p.FragmentPart = partIdx; p.FragmentsTotal = (ushort)totalPackets; p.MarkFragmented(); Buffer.BlockCopy(poolingPacket.RawData, headerSize + partIdx * maximumDataSize, p.RawData, NetPacket.FragmentedHeaderTotalSize, sendLength); IPacketFilter f = _channelOption.PacketFilter; while (f != null) { p = f.Encode(p); f = f.NextFilter; } channel.SendAsync(p); dataSize -= sendLength; } } finally { NetPool.PacketPool.Free(poolingPacket); } return; } IPacketFilter filter = _channelOption.PacketFilter; while (filter != null) { poolingPacket = filter.Encode(poolingPacket); filter = filter.NextFilter; } Interlocked.Increment(ref _statistic.UdpPacketSentCount); channel.SendAsync(poolingPacket); }
public bool SendPendingPacket() { // 응답패킷을 보내야 한다면 if (_sendAcks == true) { // lock에 비용이 많이드므로 먼저 체크한번 하고 나중에 또 체크하자 lock (_ackPacket) { if (_sendAcks == true) { _sendAcks = false; IPacketFilter filter = _channelOption.PacketFilter; if (filter != null) { var poolingPacket = NetPool.PacketPool.Alloc(_ackPacket, 0); try { while (filter != null) { poolingPacket = filter.Encode(poolingPacket); filter = filter.NextFilter; } _udpChannel.SendTo(poolingPacket.RawData, 0, poolingPacket.Size, UdpChannel.SendMode.Buffered); } finally { NetPool.PacketPool.Free(poolingPacket); } } else { _udpChannel.SendTo(_ackPacket.RawData, 0, _ackPacket.Size, UdpChannel.SendMode.Buffered); } } } } lock (_pendingPackets) { long nowTicks = DateTime.UtcNow.Ticks; lock (_sendQueue) { while (_sendQueue.Count > 0) { int relate = NetUtil.RelativeSequenceNumber(_localSequence, _localWindowStart); if (relate >= WindowSize) { break; } NetPacket packet = _sendQueue.Dequeue(); packet.Sequence = (ushort)_localSequence; _pendingPackets[_localSequence % WindowSize].Init(packet, nowTicks); _localSequence = (_localSequence + 1) % NetPacket.MaxSequence; } } for (int pendingSeq = _localWindowStart; pendingSeq != _localSequence; pendingSeq = (pendingSeq + 1) % NetPacket.MaxSequence) { if (_pendingPackets[pendingSeq % WindowSize].TrySend( nowTicks, _channelOption.RudpDisconnectTimeout, _udpChannel, _statistic) == false) { return(false); } } } return(true); }
public bool SendPendingPacket() { if (_reliable && _sendQueue.Count == 0) { long currentTime = DateTime.UtcNow.Ticks; long packetHoldTime = currentTime - _lastPacketSendTime; if (packetHoldTime < _udpChannel.ResendDelay * TimeSpan.TicksPerMillisecond) { return(true); } var packet = _lastPacket; if (packet != null) { _lastPacketSendTime = currentTime; _udpChannel.SendTo(packet.RawData, 0, packet.Size, UdpChannel.SendMode.Buffered); } } else { lock (_sendQueue) { while (_sendQueue.Count > 0) { NetPacket packet = _sendQueue.Dequeue(); _localSequence = (_localSequence + 1) % NetPacket.MaxSequence; packet.Sequence = (ushort)_localSequence; _udpChannel.SendTo(packet.RawData, 0, packet.Size, UdpChannel.SendMode.Buffered); if (_reliable && _sendQueue.Count == 0) { _lastPacketSendTime = DateTime.UtcNow.Ticks; _lastPacket = packet; } else { NetPool.PacketPool.Free(packet); } } } } if (_reliable && _mustSendAck) { _mustSendAck = false; _ackPacket.Sequence = _remoteSequence; IPacketFilter filter = _channelOption.PacketFilter; if (filter != null) { var poolingPacket = NetPool.PacketPool.Alloc(_ackPacket, 0); try { while (filter != null) { poolingPacket = filter.Encode(poolingPacket); filter = filter.NextFilter; } _udpChannel.SendTo(poolingPacket.RawData, 0, poolingPacket.Size, UdpChannel.SendMode.Buffered); } finally { NetPool.PacketPool.Free(poolingPacket); } } else { _udpChannel.SendTo(_ackPacket.RawData, 0, _ackPacket.Size, UdpChannel.SendMode.Buffered); } } return(true); }