private int HandleSendReliable(Peer peer, Protocol.Send.Reliable command, Buffer buffer) { if (command.ChannelID >= peer.ChannelCount) { return(-1); } if (peer.State != PeerState.CONNECTED && peer.State != PeerState.DISCONNECT_LATER) { return(-1); } if (command.DataLength > buffer.BytesLeft) { return(-1); } var packet = new Packet(command.DataLength, PacketFlags.RELIABLE); buffer.ReadBytes(packet.Data, 0, command.DataLength); if (peer.QueueIncomingCommand(command, packet, 0) == null) { return(-1); } return(0); }
public int Send(byte channelID, Packet packet) { if (State != PeerState.CONNECTED || channelID >= ChannelCount) { return(-1); } var channel = Channels[channelID]; uint fragmentLength = MTU - Host.Version.MaxHeaderSizeSend - Protocol.Send.Fragment.SIZE; if (packet.DataLength > fragmentLength) { ushort startSequenceNumber = (ushort)(channel.OutgoingReliableSequenceNumber + 1); uint fragmentCount = (packet.DataLength + fragmentLength - 1u) / fragmentLength; uint fragmentNumber = 0; uint fragmentOffset = 0; for (; fragmentOffset < packet.DataLength; fragmentOffset += fragmentLength, fragmentNumber++) { if (packet.DataLength - fragmentOffset < fragmentLength) { fragmentLength = packet.DataLength - fragmentOffset; } var fragment = new OutgoingCommand { FragmentOffset = fragmentOffset, FragmentLength = (ushort)fragmentLength, Packet = packet, Command = new Protocol.Send.Fragment { Flags = ProtocolFlag.ACKNOWLEDGE, ChannelID = channelID, StartSequenceNumber = startSequenceNumber, DataLength = (ushort)fragmentLength, FragmentCount = fragmentCount, FragmentNumber = fragmentNumber, TotalLength = packet.DataLength, FragmentOffset = fragmentOffset, } }; SetupOutgoingCommand(fragment); } return(0); } Protocol command; if (packet.Flags.HasFlag(PacketFlags.RELIABLE)) { command = new Protocol.Send.Reliable { ChannelID = channelID, Flags = ProtocolFlag.ACKNOWLEDGE, DataLength = (ushort)packet.DataLength, }; } else if (packet.Flags.HasFlag(PacketFlags.UNSEQUENCED)) { command = new Protocol.Send.Unsequenced { ChannelID = channelID, Flags = ProtocolFlag.UNSEQUENCED, UnsequencedGroup = (ushort)(OutgoingUnsequencedGroup + 1), DataLength = (ushort)packet.DataLength, }; } else if (channel.OutgoingReliableSequenceNumber >= 0xFFFFu) { command = new Protocol.Send.Reliable { ChannelID = channelID, Flags = ProtocolFlag.ACKNOWLEDGE, DataLength = (ushort)packet.DataLength, }; } else { command = new Protocol.Send.Unreliable { ChannelID = channelID, UnreliableSequenceNumber = (ushort)(channel.OutgoingUnreliableSequenceNumber + 1), DataLength = (ushort)packet.DataLength, }; } if (QueueOutgoingCommand(command, packet, 0, (ushort)packet.DataLength) == null) { return(-1); } return(0); }