private void BeginReceive_UDP_Client_Callback(IAsyncResult ar) { // End the operation and display the received data on // the console. UdpClient u = ((UdpState)(ar.AsyncState)).u; IPEndPoint e = ((UdpState)(ar.AsyncState)).e; // UdpClient client = NetworkPacket NewP = new NetworkPacket(); NewP.FromByteArray(UdpClient.EndReceive(ar, ref e)); NewP.ToString(); CheckLostnotReceivedPacket(NewP.Packet_Id); Console.WriteLine(" Packet Loss Percentage : " + PacketLossPercentage() + " %"); Console.WriteLine(NewP.ToString() + "\n"); // Console.WriteLine("New Packet Received From " + e.ToString() + " " + NewP.ToString()); if (OnMessageReceived != null) { OnMessageReceived.Invoke(NewP); } // Continue Reading Packets UdpState s = new UdpState(); s.e = new IPEndPoint(Local_IP, Client_Port); s.u = UdpClient; UdpClient.BeginReceive(BeginReceive_UDP_Client_Callback, s); }
public NetworkPacket ReadRawPacket() { var remoteEP = new IPEndPoint(IPAddress.Any, 0); byte[] data = udpClient.Receive(ref remoteEP); Debug.Assert(remoteEP.Equals(endpoint)); return(NetworkPacket.FromByteArray(data)); }
private void BeginReceive_UDP_Client_Callback(IAsyncResult ar) { // End the operation and display the received data on // the console. UdpClient u = ((UdpState)(ar.AsyncState)).u; IPEndPoint e = ((UdpState)(ar.AsyncState)).e; NetworkPacket NewP = new NetworkPacket(); NewP.FromByteArray(Udp_Server.EndReceive(ar, ref e)); foreach (PlayerNetworkCommunication rp in Clients_List.Values) { if (rp != null && rp.CLientAddress.Address.ToString() == e.Address.ToString() && rp.CLientAddress.Port == e.Port) { if (Server._OnMessageReceivedFromPlayer != null) { Server._OnMessageReceivedFromPlayer.Invoke(rp, NewP); } Console.WriteLine("New Packet Received From " + e.ToString() + " ==> " + NewP.ToString()); Server.Broadcast_TCP(NewP, rp); rp.CheckLostnotReceivedPacket(NewP.Packet_Id); Console.WriteLine(" Packet Loss Percentage : " + rp.PacketLossPercentage() + " % "); } } // Continue Reading Packets UdpState s = new UdpState(); s.e = new IPEndPoint(Local_IP, Server_Port); s.u = Udp_Server; Udp_Server.BeginReceive(BeginReceive_UDP_Client_Callback, s); }
private void RecvThread() { while (Active) { try { var from = new IPEndPoint(0, 0); var recvBuffer = udpClient.Receive(ref from); if (recvBuffer == null || recvBuffer.Length == 0) { continue; } NetworkPacket packet = NetworkPacket.FromByteArray(recvBuffer); if ((packet.from != remoteId && packet.from != 0) || (packet.to != localId && packet.to != 0)) { continue; } switch (packet.packetType) { case PacketType.SYN: case PacketType.SYN_ACK: throw new InvalidOperationException(); case PacketType.FIN: SendRawPacket(new NetworkPacket() { packetType = PacketType.FIN, from = localId, to = remoteId }); Reset(); break; case PacketType.Raw: if (packet.channel != (byte)EStreamChannel.KEstreamChannelDiscovery) { throw new InvalidOperationException(); } TypedMessage msg = TypedMessage.FromByteArray(packet.payload); EStreamDiscoveryMessage msgType = (EStreamDiscoveryMessage)msg.messageType; switch (msgType) { case EStreamDiscoveryMessage.KEstreamDiscoveryPingRequest: msg.messageType = (byte)EStreamDiscoveryMessage.KEstreamDiscoveryPingResponse; SendRawPacket(new NetworkPacket() { packetType = PacketType.Raw, from = packet.to, to = packet.from, channel = (byte)EStreamChannel.KEstreamChannelDiscovery, payload = msg.ToByteArray() }); break; default: throw new InvalidOperationException(); } break; case PacketType.Reliable: case PacketType.ReliableFragment: case PacketType.Unreliable: case PacketType.UnreliableFragment: ChannelData channelData = channels.GetOrNew(packet.channel); if (!channelData.receiveQueue.ContainsKey(packet.seq)) { channelData.receiveQueue.Add(packet.seq, packet); if (packet.seq < channelData.remoteSeq) { Console.WriteLine("WARNING! Late packet " + packet.seq + " we are already at " + channelData.remoteSeq); } } else { Console.WriteLine("WARNING! Got a resend of " + packet.seq); } // TODO: Clear the recv queue ushort?lastValidPacketSeq = channelData.remoteSeq > 0 ? (ushort)(channelData.remoteSeq - 1) : (ushort?)null; bool droppedIncompletePacket = false; foreach (NetworkPacket firstPacket in channelData.receiveQueue.Values) { if (firstPacket.seq < channelData.remoteSeq) { continue; } if (firstPacket.packetType == PacketType.ReliableFragment || firstPacket.packetType == PacketType.UnreliableFragment) { continue; } // Check if the packet has all the fragments bool isComplete = true; for (ushort neededSeq = firstPacket.seq; neededSeq <= firstPacket.seq + firstPacket.fragment; ++neededSeq) { if (!channelData.receiveQueue.ContainsKey(neededSeq)) { isComplete = false; break; } else { lastValidPacketSeq = neededSeq; } } if (!isComplete) { // The packet is not yet fully complete if (firstPacket.packetType == PacketType.Unreliable) { droppedIncompletePacket = true; continue; // this is unreliable so check if maybe next packet is complete } else { break; // we cannot skip any packet on reliable transports } } if (channelData.remoteSeq != firstPacket.seq) { Console.WriteLine("WARNING! Dropping unreliable packets! Jump from " + channelData.remoteSeq + " to " + firstPacket.seq + (droppedIncompletePacket ? " (previous incomplete)" : "")); } // We have a complete packet, receive it List <NetworkPacket> reassembleList = new List <NetworkPacket>(); for (ushort seq = firstPacket.seq; seq <= firstPacket.seq + firstPacket.fragment; ++seq) { if (seq != firstPacket.seq) { if (firstPacket.packetType == PacketType.Reliable) { Debug.Assert(channelData.receiveQueue[seq].packetType == PacketType.ReliableFragment); } else if (firstPacket.packetType == PacketType.Unreliable) { Debug.Assert(channelData.receiveQueue[seq].packetType == PacketType.UnreliableFragment); } else { Debug.Assert(false); } } reassembleList.Add(channelData.receiveQueue[seq]); } DataPacket dataPacket = ReassembleDataPacket(reassembleList); try { OnPacketReceived?.Invoke(dataPacket); } catch (Exception e) { Console.WriteLine(e); } channelData.remoteSeq = (ushort)(firstPacket.seq + firstPacket.fragment + 1); } if ((packet.packetType == PacketType.Reliable || packet.packetType == PacketType.ReliableFragment) && lastValidPacketSeq.HasValue) { using (MemoryStream ms = new MemoryStream()) using (BinaryWriter writer = new BinaryWriter(ms)) { writer.Write(channelData.receiveQueue[lastValidPacketSeq.Value].timestamp); writer.Flush(); SendRawPacket(new NetworkPacket() { packetType = PacketType.ReliableACK, from = localId, to = remoteId, channel = packet.channel, seq = lastValidPacketSeq.Value, payload = ms.ToArray() }); } } break; case PacketType.ReliableACK: //Console.WriteLine("ACKed channel=" + packet.channel + ", seq=" + packet.seq); // TODO break; } } catch (SocketException) { } catch (Exception e) { Console.WriteLine(e); } } }