public void Update() { lock (readyBuffers) { buffersToProcess.AddRange(readyBuffers); readyBuffers.Clear(); } foreach (var bufferToProcess in buffersToProcess) { HandleMessageReceived(bufferToProcess.Endpoint, bufferToProcess.Buffer, bufferToProcess.NumBytesReceived); receivedBuffers.Push(bufferToProcess); } buffersToProcess.Clear(); #if DEBUG lock (receivedBuffersForShuffling) { for (int i = receivedBuffersForShuffling.Count - 1; i >= 0; i--) { var deferred = receivedBuffersForShuffling[i]; if (deferred.TimeToReceiveTicks <= Environment.TickCount) { NeutrinoConfig.LogWarning(Name + " injecting shuffled receipt..."); HandleMessageReceived(deferred.Endpoint, deferred.ReceivedBuffer, deferred.ReceivedBuffer.Length); receivedBuffersForShuffling.RemoveAt(i); } } } #endif foreach (NetworkPeer c in peersByEndpoint.Values) { c.Update(); if (!c.IsConnected) { peersPendingDisconnect.Add(c); } } foreach (NetworkPeer c in peersPendingDisconnect) { DisconnectPeer(c); } peersPendingDisconnect.Clear(); }
private void HandleMessageReceived(IAsyncResult result) { if (serverSocket != null) { try { #if DEBUG if (SimulatedPacketLossRate > 0.0 && (randomGenerator.NextDoublePositive() <= SimulatedPacketLossRate)) { NeutrinoConfig.LogWarning("SIMULATING PACKET LOSS!"); receivedEndPoint = new IPEndPoint(IPAddress.Any, 0); IAsyncResult asyncResult = serverSocket.BeginReceiveFrom(receiveBuffer, 0, NeutrinoConfig.MaxMessageSize, SocketFlags.None, ref receivedEndPoint, new AsyncCallback(HandleMessageReceived), null); if (asyncResult.CompletedSynchronously) { HandleMessageReceived(asyncResult); } return; } else if (SimulatedPacketShuffleRate > 0.0 && (randomGenerator.NextDoublePositive() <= SimulatedPacketShuffleRate)) { NeutrinoConfig.LogWarning("SIMULATING PACKET OUT OF ORDER!"); int numReceived = serverSocket.EndReceiveFrom(result, ref receivedEndPoint); byte[] receivedForShuffle = new byte[numReceived]; Array.Copy(receiveBuffer, receivedForShuffle, numReceived); lock (receivedBuffersForShuffling) { receivedBuffersForShuffling.Add(new DeferredReceivable() { ReceivedBuffer = receivedForShuffle, TimeToReceiveTicks = Environment.TickCount + (int)(randomGenerator.NextDoublePositive() * 100.0), Endpoint = (IPEndPoint)receivedEndPoint }); } receivedEndPoint = new IPEndPoint(IPAddress.Any, 0); IAsyncResult asyncResult = serverSocket.BeginReceiveFrom(receiveBuffer, 0, NeutrinoConfig.MaxMessageSize, SocketFlags.None, ref receivedEndPoint, new AsyncCallback(HandleMessageReceived), null); if (asyncResult.CompletedSynchronously) { HandleMessageReceived(asyncResult); } return; } #endif int numBytesReceived = serverSocket.EndReceiveFrom(result, ref receivedEndPoint); var receivedBuffer = receivedBuffers.Pop(); Array.Copy(receiveBuffer, receivedBuffer.Buffer, numBytesReceived); receivedBuffer.NumBytesReceived = numBytesReceived; receivedBuffer.Endpoint = (IPEndPoint)receivedEndPoint; lock (readyBuffers) readyBuffers.Add(receivedBuffer); } catch (Exception ex) { NeutrinoConfig.LogError("Error handling message: " + ex); } // TBD: When tests are complete, test whether we need to reallocate here? receivedEndPoint = new IPEndPoint(IPAddress.Any, 0); IAsyncResult repeatAsyncResult = serverSocket.BeginReceiveFrom(receiveBuffer, 0, NeutrinoConfig.MaxMessageSize, SocketFlags.None, ref receivedEndPoint, new AsyncCallback(HandleMessageReceived), null); if (repeatAsyncResult.CompletedSynchronously) { HandleMessageReceived(repeatAsyncResult); } } }