bool ReadDataInner(Server server) { var rx = new byte[1024]; var len = 0; for (; ;) { try { //Poll the socket first to see if there's anything there. if (!Socket.Poll(0, SelectMode.SelectRead)) { break; } if (0 < (len = Socket.Receive(rx))) { Data.AddRange(rx.Take(len)); } else { if (len == 0) { server.DropClient(this); } break; } } catch (SocketException ex) { if (ex.SocketErrorCode == SocketError.WouldBlock) { break; } server.DropClient(this); return(false); } } lastReceivedTime = WarGame.RunTime; TimeoutMessageShown = false; return(true); }
public void ReadData(Server server) { if (ReadDataInner(server)) { while (Data.Count >= ExpectLength) { var bytes = PopBytes(ExpectLength); switch (State) { case ReceiveState.Header: { ExpectLength = BitConverter.ToInt32(bytes, 0) - 4; Frame = BitConverter.ToInt32(bytes, 4); State = ReceiveState.Data; if (ExpectLength < 0 || ExpectLength > MaxOrderLength) { server.DropClient(this); return; } } break; case ReceiveState.Data: { if (MostRecentFrame < Frame) { MostRecentFrame = Frame; } server.DispatchOrders(this, Frame, bytes); ExpectLength = 8; State = ReceiveState.Header; } break; } } } }
void ITick.Tick(S server) { if ((WarGame.RunTime - lastPing) > PingInterval || isInitialPing) { isInitialPing = false; lastPing = WarGame.RunTime; //Ignore client timeout in singleplayer games to make debugging easier if (server.LobbyInfo.NonBotClients.Count() < 2 && !server.Dedicated) { foreach (var c in server.Conns.ToList()) { server.SendOrderTo(c, "Ping", WarGame.RunTime.ToString()); } } else { foreach (var c in server.Conns.ToList()) { if (c == null || c.Socket == null) { continue; } var client = server.GetClient(c); if (client == null) { server.DropClient(c); server.SendMessage("A player has been dropped after timing out."); continue; } if (c.TimeSinceLastResponse < ConnTimeout) { server.SendOrderTo(c, "Ping", WarGame.RunTime.ToString()); if (!c.TimeoutMessageShown && c.TimeSinceLastResponse > PingInterval * 2) { server.SendMessage(client.Name + " is experiencing connection problems."); c.TimeoutMessageShown = true; } } else { server.SendMessage(client.Name + " has benn dropped after timing out."); server.DropClient(c); } } } if (WarGame.RunTime - lastConnReport > ConnReportInterval) { lastConnReport = WarGame.RunTime; var timeouts = server.Conns.Where(c => c.TimeSinceLastResponse > ConnReportInterval && c.TimeSinceLastResponse < ConnTimeout).OrderBy(c => c.TimeSinceLastResponse); foreach (var c in timeouts) { if (c == null || c.Socket == null) { continue; } var client = server.GetClient(c); if (client != null) { server.SendMessage("{0} will be dropped in {1} seconds.".F(client.Name, (ConnTimeout - c.TimeSinceLastResponse) / 1000)); } } } } }