private void SetupClient(BMSByte packet, string incomingEndpoint, IPEndPoint groupEP) { // Check for a local listing request if (packet.Size.Between(2, 4) && packet[0] == BROADCAST_LISTING_REQUEST_1 && packet[1] == BROADCAST_LISTING_REQUEST_2 && packet[2] == BROADCAST_LISTING_REQUEST_3) { // Don't reply if the server is not currently accepting connections if (!AcceptingConnections) { return; } // This may be a local listing request so respond with the server flag byte Client.Send(new byte[] { SERVER_BROADCAST_CODE }, 1, groupEP); return; } if (Players.Count == MaxConnections) { // Tell the client why they are being disconnected Send(Error.CreateErrorMessage(Time.Timestep, "Max Players Reached On Server", false, MessageGroupIds.MAX_CONNECTIONS, true)); // Send the close connection frame to the client Send(new ConnectionClose(Time.Timestep, false, Receivers.Target, MessageGroupIds.DISCONNECT, false)); return; } else if (!AcceptingConnections) { // Tell the client why they are being disconnected Send(Error.CreateErrorMessage(Time.Timestep, "The server is busy and not accepting connections", false, MessageGroupIds.MAX_CONNECTIONS, true)); // Send the close connection frame to the client Send(new ConnectionClose(Time.Timestep, false, Receivers.Target, MessageGroupIds.DISCONNECT, false)); return; } // Validate that the connection headers are properly formatted byte[] response = Websockets.ValidateConnectionHeader(packet.CompressBytes()); // The response will be null if the header sent is invalid, if so then disconnect client as they are sending invalid headers if (response == null) { return; } UDPNetworkingPlayer player = new UDPNetworkingPlayer(ServerPlayerCounter++, incomingEndpoint, false, groupEP, this); // If all is in order then send the validated response to the client Client.Send(response, response.Length, groupEP); OnPlayerConnected(player); udpPlayers.Add(incomingEndpoint, player); // The player has successfully connected player.Connected = true; }
private void HandleMaximumClientPacketResponse(string incomingEndpoint, IPEndPoint groupEP) { // Tell the client why they are being disconnected Error frame = Error.CreateErrorMessage(Time.Timestep, "Max Players Reached On Server", false, MessageGroupIds.MAX_CONNECTIONS, false); var playerToDisconnect = new UDPNetworkingPlayer(ServerPlayerCounter++, incomingEndpoint, false, groupEP, this); UDPPacketComposer.SendNewUDPPacket(this, playerToDisconnect, frame, false); // Send the close connection frame to the client UDPPacketComposer.SendNewUDPPacket(this, playerToDisconnect, new ConnectionClose(Time.Timestep, false, Receivers.Target, MessageGroupIds.DISCONNECT, false), false); }
private void HandleNotAcceptingConnectionsPacketResponse(string incomingEndpoint, IPEndPoint groupEP) { // Tell the client why they are being disconnected var frame = Error.CreateErrorMessage(Time.Timestep, "The server is busy and not accepting connections", false, MessageGroupIds.NOT_ACCEPT_CONNECTIONS, false); var playerToDisconnect = new UDPNetworkingPlayer(ServerPlayerCounter++, incomingEndpoint, false, groupEP, this); UDPPacketComposer.SendNewUDPPacket(this, playerToDisconnect, frame, false); // Send the close connection frame to the client UDPPacketComposer.SendNewUDPPacket(this, playerToDisconnect, new ConnectionClose(Time.Timestep, false, Receivers.Target, MessageGroupIds.DISCONNECT, false), false); }
private void HandleClientAcceptance(BMSByte packet, string incomingEndpoint, IPEndPoint groupEP) { // Validate that the connection headers are properly formatted byte[] response = Websockets.ValidateConnectionHeader(packet.CompressBytes()); // The response will be null if the header sent is invalid, if so then disconnect client as they are sending invalid headers if (response == null) { return; } var player = new UDPNetworkingPlayer(ServerPlayerCounter++, incomingEndpoint, false, groupEP, this); // If all is in order then send the validated response to the client Client.Send(response, response.Length, groupEP); OnPlayerConnected(player); udpPlayers.Add(incomingEndpoint, player); // The player has successfully connected player.Connected = true; }
/// <summary> /// Infinite loop listening for new data from all connected clients on a separate thread. /// This loop breaks when readThreadCancel is set to true /// </summary> /// <summary> ///无限循环在单独的线程上监听来自所有连接客户端的新数据。 ///当readThreadCancel设置为true时,此循环中断 /// </ summary> private void ReadClients() { IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 0); string incomingEndpoint = string.Empty; BMSByte packet = null; // 故意无限循环 // Intentional infinite loop while (IsBound) { //如果读取已被标记为取消,则从此循环中断开 // If the read has been flagged to be canceled then break from this loop if (readThreadCancel) { return; } try { //从网络读取数据包 // Read a packet from the network packet = Client.Receive(ref groupEP, ref incomingEndpoint); // 模拟丢包 if (PacketLossSimulation > 0.0f && new Random().NextDouble() <= PacketLossSimulation) { // 丢掉这个消息 // Skip this message continue; } // 统计 宽带接收数据大小 BandwidthIn += (ulong)packet.Size; } catch { // 如果出错, 就查找该IP PROT的玩家,将该玩家踢掉 UDPNetworkingPlayer player; if (udpPlayers.TryGetValue(incomingEndpoint, out player)) { FinalizeRemovePlayer(player, true); } continue; } //检查以确保收到消息 // Check to make sure a message was received if (packet == null || packet.Size <= 0) { continue; } //如果玩家列表里不包含该包的发送者 if (!udpPlayers.ContainsKey(incomingEndpoint)) { // 创建该发送者的结构体保存 UDPNetworkingPlayer SetupClient(packet, incomingEndpoint, groupEP); continue; } else { currentReadingPlayer = udpPlayers[incomingEndpoint]; if (!currentReadingPlayer.Accepted && !currentReadingPlayer.PendingAccepted) { //响应验证可能会被丢弃 //检查客户端是否正在重新发送响应 // It is possible that the response validation was dropped so // check if the client is resending for a response byte[] response = Websockets.ValidateConnectionHeader(packet.CompressBytes()); //客户端再次发送连接请求 // The client has sent the connection request again if (response != null) { Client.Send(response, response.Length, groupEP); continue; } else { // 将该玩家设置为等待接受确认 currentReadingPlayer.PendingAccepted = true; // 读取该玩家发来的数据包 ReadPacket(packet); } } else { //由于Forge网络协议,数据包唯一的时间1 //将是71,第二个数据包是69是强制断开连接 // Due to the Forge Networking protocol, the only time that packet 1 // will be 71 and the second packet be 69 is a forced disconnect reconnect if (packet[0] == 71 && packet[1] == 69) { udpPlayers.Remove(currentReadingPlayer.Ip + "+" + currentReadingPlayer.Port); FinalizeRemovePlayer(currentReadingPlayer, true); continue; } // 设置玩家最好ping时间 currentReadingPlayer.Ping(); // 读取该玩家发来的数据包 ReadPacket(packet); } } } }
/// <summary> /// Infinite loop listening for new data from all connected clients on a separate thread. /// This loop breaks when readThreadCancel is set to true /// </summary> private void ReadClients() { IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 0); string incomingEndpoint = string.Empty; BMSByte packet = null; // Intentional infinite loop while (IsBound) { // If the read has been flagged to be canceled then break from this loop if (readThreadCancel) { return; } try { // Read a packet from the network packet = Client.Receive(ref groupEP, ref incomingEndpoint); if (PacketLossSimulation > 0.0f && new Random().NextDouble() <= PacketLossSimulation) { // Skip this message continue; } BandwidthIn += (ulong)packet.Size; } catch { UDPNetworkingPlayer player; if (udpPlayers.TryGetValue(incomingEndpoint, out player)) { FinalizeRemovePlayer(player, true); } continue; } // Check to make sure a message was received if (packet == null || packet.Size <= 0) { continue; } if (!udpPlayers.ContainsKey(incomingEndpoint)) { SetupClient(packet, incomingEndpoint, groupEP); continue; } else { currentReadingPlayer = udpPlayers[incomingEndpoint]; if (!currentReadingPlayer.Accepted && !currentReadingPlayer.PendingAccepted) { // It is possible that the response validation was dropped so // check if the client is resending for a response byte[] response = Websockets.ValidateConnectionHeader(packet.CompressBytes()); // The client has sent the connection request again if (response != null) { Client.Send(response, response.Length, groupEP); continue; } else { currentReadingPlayer.PendingAccepted = true; ReadPacket(packet); } } else { // Due to the Forge Networking protocol, the only time that packet 1 // will be 71 and the second packet be 69 is a forced disconnect reconnect if (packet[0] == 71 && packet[1] == 69) { udpPlayers.Remove(currentReadingPlayer.Ip + "+" + currentReadingPlayer.Port); FinalizeRemovePlayer(currentReadingPlayer, true); continue; } currentReadingPlayer.Ping(); ReadPacket(packet); } } } }
/// <summary> /// Infinite loop listening for new data from all connected clients on a separate thread. /// This loop breaks when readThreadCancel is set to true /// </summary> private void ReadClients() { IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 0); string incomingEndpoint = string.Empty; BMSByte packet = null; // Intentional infinite loop while (IsBound) { // If the read has been flagged to be canceled then break from this loop if (readThreadCancel) { return; } try { // Read a packet from the network packet = Client.Receive(ref groupEP, ref incomingEndpoint); if (PacketLossSimulation > 0.0f && new Random().NextDouble() <= PacketLossSimulation) { // Skip this message continue; } BandwidthIn += (ulong)packet.Size; } catch (Exception ex) when(!(ex is SocketException)) { Console.WriteLine($"Error in ReadClients() infinite loop, error was {ex.Message}"); UDPNetworkingPlayer player; if (udpPlayers.TryGetValue(incomingEndpoint, out player)) { Console.WriteLine($"Following the error, player '{player.NetworkId}' will be removed"); FinalizeRemovePlayer(player, true); } continue; } // Check to make sure a message was received if (packet == null || packet.Size <= 0) { continue; } if (!udpPlayers.ContainsKey(incomingEndpoint)) { SetupClient(packet, incomingEndpoint, groupEP); continue; } else { currentReadingPlayer = udpPlayers[incomingEndpoint]; if (!currentReadingPlayer.Accepted && !currentReadingPlayer.PendingAccepted) { // It is possible that the response validation was dropped so // check if the client is resending for a response byte[] response = Websockets.ValidateConnectionHeader(packet.CompressBytes()); // The client has sent the connection request again if (response != null) { Client.Send(response, response.Length, groupEP); continue; } else { currentReadingPlayer.PendingAccepted = true; ReadPacket(packet); } } else { currentReadingPlayer.Ping(); ReadPacket(packet); } } } }
/// <summary> /// Infinite loop listening for new data from all connected clients on a separate thread. /// This loop breaks when readThreadCancel is set to true /// </summary> private void ReadClients() { IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 0); string incomingEndpoint = string.Empty; BMSByte packet = null; // Intentional infinite loop while (IsBound) { // If the read has been flagged to be canceled then break from this loop if (readThreadCancel) { return; } try { // Read a packet from the network packet = Client.Receive(ref groupEP, ref incomingEndpoint); if (PacketLossSimulation > 0.0f && new Random().NextDouble() <= PacketLossSimulation) { // Skip this message continue; } BandwidthIn += (ulong)packet.Size; } catch { if (udpPlayers.ContainsKey(incomingEndpoint)) { Disconnect(udpPlayers[incomingEndpoint], true); CleanupDisconnections(); } continue; } // Check to make sure a message was received if (packet == null || packet.Size <= 0) { continue; } if (!udpPlayers.ContainsKey(incomingEndpoint)) { SetupClient(packet, incomingEndpoint, groupEP); continue; } else { currentReadingPlayer = udpPlayers[incomingEndpoint]; if (!currentReadingPlayer.Accepted && !currentReadingPlayer.PendingAccpeted) { // It is possible that the response validation was dropped so // check if the client is resending for a response byte[] response = Websockets.ValidateConnectionHeader(packet.CompressBytes()); // The client has sent the connection request again if (response != null) { Client.Send(response, response.Length, groupEP); continue; } else { currentReadingPlayer.PendingAccpeted = true; ReadPacket(packet); } } else { ReadPacket(packet); } } } }