public void GetNetworkTime() { if (SyncedTime != null) { return; } var ntpData = new byte[48]; //LeapIndicator = 0 (no warning) //VersionNum = 3 //Mode = 3 (Client Mode) ntpData[0] = 0x1B; //send _socket.SendTo(ntpData, _ntpEndPoint); //receive NetEndPoint endPoint = new NetEndPoint(ConnectionAddressType.IPv4, 0); int errorCode = 0; if (_socket.ReceiveFrom(ref ntpData, ref endPoint, ref errorCode) > 0 && endPoint.Equals(_ntpEndPoint)) { ulong intPart = (ulong)ntpData[40] << 24 | (ulong)ntpData[41] << 16 | (ulong)ntpData[42] << 8 | (ulong)ntpData[43]; ulong fractPart = (ulong)ntpData[44] << 24 | (ulong)ntpData[45] << 16 | (ulong)ntpData[46] << 8 | (ulong)ntpData[47]; var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L); SyncedTime = (new DateTime(1900, 1, 1)).AddMilliseconds((long)milliseconds); } }
private void ReceiveLogic() { while (_running) { int errorCode = 0; //Receive some info byte[] reusableBuffer = null; int result = _socket.ReceiveFrom(ref reusableBuffer, ref _remoteEndPoint, ref errorCode); if (result > 0) { #if DEBUG bool receivePacket = true; if (SimulatePacketLoss && _randomGenerator.Next(100 / SimulationPacketLossChance) == 0) { receivePacket = false; } else if (SimulateLatency) { int latency = _randomGenerator.Next(SimulationMaxLatency); if (latency > 5) { byte[] holdedData = new byte[result]; Buffer.BlockCopy(reusableBuffer, 0, holdedData, 0, result); _pingSimulationList.AddFirst(new IncomingData { Data = holdedData, EndPoint = _remoteEndPoint, TimeWhenGet = DateTime.UtcNow.AddMilliseconds(latency) }); receivePacket = false; } } if (receivePacket) //DataReceived #endif //ProcessEvents DataReceived(reusableBuffer, result, _remoteEndPoint); } else if (result < 0) { //10054 - remote close (not error) //10040 - message too long (impossible now) if (errorCode != 10054) { NetUtils.DebugWrite(ConsoleColor.Red, "(NB)Socket error!"); ProcessError("Receive socket error: " + errorCode); Stop(); return; } } #if DEBUG if (SimulateLatency) { var node = _pingSimulationList.First; var time = DateTime.UtcNow; while (node != null) { var incomingData = node.Value; if (incomingData.TimeWhenGet <= time) { DataReceived(incomingData.Data, incomingData.Data.Length, incomingData.EndPoint); var nodeToRemove = node; node = node.Next; _pingSimulationList.Remove(nodeToRemove); } else { node = node.Next; } } } #endif } }