public bool GetUDPMessage(out byte[] data, out int length, out IPEndPoint endPoint) { long currentTime = DateTime.UtcNow.Ticks; foreach (KeyValuePair <int, ReliableHandler> kvp in reliableHandlers) { int clientID = kvp.Key; if (udpMappings.TryGetValue(clientID, out endPoint)) { ReliableHandler rh = kvp.Value; rh.SendToUDP(out int sendSequence, out int sendACK, out byte[] sendData); //Skip ACK only messages if we sent a message within ACK_INTERVAL. if (sendSequence == -1 && (currentTime - rh.lastUDPSend) < ACK_INTERVAL) { continue; } rh.lastUDPSend = currentTime; WriteInt32(clientID, sendBuffer, 0); WriteInt32(sendSequence, sendBuffer, 4); WriteInt32(sendACK, sendBuffer, 8); WriteInt32(0, sendBuffer, 12); length = 16; if (sendData != null) { WriteInt32(sendData.Length, sendBuffer, 12); Array.Copy(sendData, 0, sendBuffer, 16, sendData.Length); length = 16 + sendData.Length; } data = sendBuffer; udpBytesSentSecond += length; udpBytesSentTotal += length; return(true); } } if (udpSendDisconnect.TryDequeue(out int sendDisconnectClientID)) { if (udpMappings.TryGetValue(sendDisconnectClientID, out endPoint)) { WriteInt32(sendDisconnectClientID, sendBuffer, 0); WriteInt32(-2, sendBuffer, 4); WriteInt32(-2, sendBuffer, 8); WriteInt32(0, sendBuffer, 12); length = 16; data = sendBuffer; udpBytesSentSecond += length; udpBytesSentTotal += length; return(true); } } retransmitBytes = 0; foreach (KeyValuePair <int, ReliableHandler> kvp in reliableHandlers) { retransmitBytes += kvp.Value.retransmitBytes; } data = null; endPoint = null; length = 0; return(false); }
public void HandleTCPMessage(int clientID, byte[] data, int length) { tcpBytesReceivedSecond += length; tcpBytesReceivedTotal += length; ReliableHandler rh = GetClient(clientID); rh.HandleTCPData(data, length); }
public void HandleUDPMessage(byte[] data, int length, IPEndPoint endpoint) { if (length < 16) { return; } int clientID = ReadInt32(data, 0); int sequence = ReadInt32(data, 4); int ack = ReadInt32(data, 8); int dataLength = ReadInt32(data, 12); if (sequence == -2) { if (!udpIgnore.ContainsKey(clientID)) { Console.WriteLine("Tunnel connection close for " + clientID); ForgetClient(clientID); } } if (length != (16 + dataLength)) { return; } udpBytesReceivedSecond += length; udpBytesReceivedTotal += length; if (udpIgnore.TryGetValue(clientID, out long ignoreTime)) { long currentTime = DateTime.UtcNow.Ticks; if (ignoreTime > currentTime) { return; } else { udpIgnore.TryRemove(clientID, out long _); udpMappings.TryRemove(clientID, out IPEndPoint _2); } } if (!udpMappings.ContainsKey(clientID)) { Console.WriteLine("Adding new connection: " + clientID); if (tunnelServer != null) { TcpClient newClient = tunnelServer.GetNewConnection(clientID); tcpMappings.TryAdd(clientID, newClient); } udpMappings.TryAdd(clientID, new IPEndPoint(endpoint.Address, endpoint.Port)); } ReliableHandler rh = GetClient(clientID); rh.HandleUDPMessage(data, dataLength, sequence, ack); }
public ReliableHandler GetClient(int clientID) { ReliableHandler retVal = null; if (!reliableHandlers.TryGetValue(clientID, out retVal)) { retVal = new ReliableHandler(clientID); long currentTime = DateTime.UtcNow.Ticks; retVal.lastUDPSend = currentTime; retVal.lastUDPReceive = currentTime; retVal.lastTCPReceive = currentTime; reliableHandlers.TryAdd(clientID, retVal); } return(retVal); }