private void MessageLoop(object state) { var client = state as TcpClient; try { Debug.Log("Authenticating with server"); using (var networkStream = client.GetStream()) { _stream = networkStream; PerformHail(networkStream); var buffer = new byte[1024]; NetMessage dataBuffer = null; var bufferSize = 0; var lengthBuffer = new byte[2]; var bytesReceived = 0; int readBytes; var authMessages = new Queue <NetMessage>(); while (!_shutdownQueued) { readBytes = networkStream.Read(buffer, 0, buffer.Length); if (readBytes > 0) { var readMessage = NetMessage.GetMessages(buffer, readBytes, ref bytesReceived, ref dataBuffer, ref lengthBuffer, ref bufferSize, authMessages.Enqueue); if (readMessage >= 1) { break; } } if (!client.Connected) { return; } } if (authMessages.Count == 0) { throw new Exception("Could not read auth result"); } var authMsg = authMessages.Dequeue(); var auth = authMsg.ReadBoolean(); authMsg.ReadPadBits(); if (!auth) { if (!authMsg.ReadString(out var reason)) { reason = "Not authorized"; } Debug.LogError($"Could not connect to server. {reason}"); UpdateConnectionStatus(ConnectionStatus.FailedToConnect); return; } if (!authMsg.ReadGuid(out var guid)) { throw new Exception("Could not read room guid"); } Connected(guid, client); UpdateConnectionStatus(ConnectionStatus.Connected); //and drain the rest of messages that might have come after the auth while (authMessages.Count > 0) { EnqueueMessage(authMessages.Dequeue()); } while (!_shutdownQueued) { readBytes = networkStream.Read(buffer, 0, buffer.Length); if (readBytes > 0) { NetMessage.GetMessages(buffer, readBytes, ref bytesReceived, ref dataBuffer, ref lengthBuffer, ref bufferSize, EnqueueMessage); } if (!client.Connected) { return; } } } } catch (ObjectDisposedException ode) { //if (!_shutdownQueued) // Debug.LogException(ode, "{0} disposed when it shouldn't have", ode.ObjectName); } catch (IOException ioe) { if (!(ioe.InnerException is SocketException)) { Debug.LogException(ioe); } } catch (Exception e) { Debug.LogException(e); } finally { if (client != null) { client.Close(); } Disconnected(); UpdateConnectionStatus(ConnectionStatus.Disconnected); } }
private async void HandleRoomConnection(TcpClient client) { var endpoint = client.Client.RemoteEndPoint; Debug.Log("Room connection request from {0}", endpoint); client.ReceiveBufferSize = 1024; client.SendBufferSize = 1024; client.NoDelay = true; client.LingerState = new LingerOption(true, 10); Room room = null; try { using (var networkStream = client.GetStream()) { var buffer = new byte[1024]; NetMessage dataBuffer = null; var bufferSize = 0; var lengthBuffer = new byte[2]; var bytesReceived = 0; int readBytes; var authMessages = new Queue <NetMessage>(); while (_tcpRunning) { readBytes = await networkStream.ReadAsync(buffer, 0, buffer.Length, _shutdownTokenSource.Token); if (readBytes > 0) { var readMessage = NetMessage.GetMessages(buffer, readBytes, ref bytesReceived, ref dataBuffer, ref lengthBuffer, ref bufferSize, authMessages.Enqueue); if (readMessage >= 1) { break; } } if (!client.Connected) { return; } } string denyReason; if ( !ApproveRoomConnection((IPEndPoint)client.Client.RemoteEndPoint, authMessages.Count > 0 ? authMessages.Dequeue() : null, out denyReason, out room)) { var dcMessage = GetMessage(denyReason.Length * 2 + 1); dcMessage.Write(false); dcMessage.WritePadBits(); dcMessage.Write(denyReason); dcMessage.WriteSize(); await networkStream.WriteAsync(dcMessage.Data, 0, dcMessage.LengthBytes, _shutdownTokenSource.Token); return; } else { var cMessage = GetMessage(17); cMessage.Write(true); cMessage.WritePadBits(); cMessage.Write(room.Guid); cMessage.WriteSize(); await networkStream.WriteAsync(cMessage.Data, 0, cMessage.LengthBytes, _shutdownTokenSource.Token); } room.TcpClient = client; room.NetworkStream = networkStream; AddRoom(room); UpdateRoomsOfNewRoom(room); Debug.LogWarning("Room {1} connected from {0}, connectable at {2}", client.Client.RemoteEndPoint, room.RoomId, room.Address); while (authMessages.Count > 0) { room.ConsumeData(authMessages.Dequeue()); } while (_tcpRunning && room.Running) { readBytes = await networkStream.ReadAsync(buffer, 0, buffer.Length, _shutdownTokenSource.Token); if (readBytes > 0) { NetMessage.GetMessages(buffer, readBytes, ref bytesReceived, ref dataBuffer, ref lengthBuffer, ref bufferSize, room.ConsumeData); } if (!client.Connected) { return; } } } } catch (OperationCanceledException o) { Debug.Log("Operation canceled"); } catch (ObjectDisposedException ode) { if (_tcpRunning && ode.ObjectName != "System.Net.Sockets.NetworkStream") { Debug.LogException(ode, "{0} disposed when it shouldn't have", ode.ObjectName); } } catch (SocketException se) { } catch (IOException ioe) { if (!(ioe.InnerException is SocketException)) { Debug.LogException(ioe); } } catch (Exception exp) { Debug.LogException(exp); } finally { Debug.Log("Closing room connection to {0}", endpoint); client.Close(); if (room != null) { RemoveRoom(room); room.NetworkStream = null; //todo: move all players in the room to a new room. } } }
private async void ConnectCallback(IAsyncResult ar) { var client = ar.AsyncState as TcpClient; try { if (client != _serverClient) { throw new Exception("TcpClient Mismatch"); } client.EndConnect(ar); Debug.Log("Authenticating with server"); using (var networkStream = client.GetStream()) { await PerformHail(networkStream); var buffer = new byte[1024]; NetMessage dataBuffer = null; var bufferSize = 0; var lengthBuffer = new byte[2]; var bytesReceived = 0; int readBytes; var authMessages = new Queue <NetMessage>(); while (!_shutdownQueued) { readBytes = await networkStream.ReadAsync(buffer, 0, buffer.Length); if (readBytes > 0) { var readMessage = NetMessage.GetMessages(buffer, readBytes, ref bytesReceived, ref dataBuffer, ref lengthBuffer, ref bufferSize, authMessages.Enqueue); if (readMessage >= 1) { break; } } if (!client.Connected) { return; } } if (authMessages.Count == 0) { throw new Exception("Could not read auth result"); } var authMsg = authMessages.Dequeue(); var auth = authMsg.ReadBoolean(); authMsg.ReadPadBits(); if (!auth) { string reason; if (!authMsg.ReadString(out reason)) { reason = "Not authorized"; } Debug.LogError("Could not connect to server. {0}", reason); ServerStatus = ConnectionStatus.FailedToConnect; ServerStatusChanged.TryRaise(Debug.Logger); return; } Guid guid; if (!authMsg.ReadGuid(out guid)) { throw new Exception("Could not read room guid"); } RoomId = guid; Debug.Log("Connected to dispatcher. Id is {0}", RoomId); Server = new Server(this) { NetworkStream = networkStream, TcpClient = client }; ServerStatus = ConnectionStatus.Connected; ServerStatusChanged.TryRaise(Debug.Logger); //and drain the rest of messages that might have come after the auth while (authMessages.Count > 0) { EnqueueMessage(authMessages.Dequeue()); } while (!_shutdownQueued) { readBytes = await networkStream.ReadAsync(buffer, 0, buffer.Length); if (readBytes > 0) { NetMessage.GetMessages(buffer, readBytes, ref bytesReceived, ref dataBuffer, ref lengthBuffer, ref bufferSize, EnqueueMessage); } if (!client.Connected) { return; } } } } catch (ObjectDisposedException ode) { if (!_shutdownQueued) { Debug.LogException(ode, "{0} disposed when it shouldn't have", ode.ObjectName); } } catch (IOException ioe) { if (!(ioe.InnerException is SocketException)) { Debug.LogException(ioe); } } catch (Exception e) { Debug.LogException(e); } finally { if (client != null) { client.Close(); } ServerStatus = ConnectionStatus.Disconnected; ServerStatusChanged.TryRaise(Debug.Logger); } }
private async void HandleClientConnection(TcpClient client) { var endpoint = client.Client.RemoteEndPoint; Debug.Log("Player connection request from {0}", endpoint); client.ReceiveBufferSize = 1024; client.SendBufferSize = 1024; client.NoDelay = true; client.LingerState = new LingerOption(true, 10); Player player = null; try { using (var networkStream = client.GetStream()) { var buffer = new byte[1024]; NetMessage dataBuffer = null; var bufferSize = 0; var lengthBuffer = new byte[2]; var bytesReceived = 0; int readBytes; var authMessages = new Queue <NetMessage>(); while (_tcpRunning) { readBytes = await networkStream.ReadAsync(buffer, 0, buffer.Length, _shutdownTokenSource.Token); if (readBytes > 0) { var readMessage = NetMessage.GetMessages(buffer, readBytes, ref bytesReceived, ref dataBuffer, ref lengthBuffer, ref bufferSize, authMessages.Enqueue); if (readMessage >= 1) { break; } } if (!client.Connected) { return; } } player = new Player(this) { TcpClient = client, NetworkStream = networkStream, Status = ConnectionStatus.Connecting }; if (ConstructNetData != null) { player.NetUserData = ConstructNetData(); } if (VerifyPlayer != null) { if (authMessages.Count > 0) { VerifyPlayer(player, authMessages.Dequeue()); } else { player.Disconnect("No authentication message sent"); } } else { player.AllowConnect(); } var canConnect = await player.AllowConnectCompletion.Task; if (!canConnect) { return; } player.Status = ConnectionStatus.Connected; FinalizePlayerAdd(player); Debug.Log("Client connected from {0}", client.Client.RemoteEndPoint); //and drain the rest of messages that might have come after the auth while (authMessages.Count > 0) { player.ConsumeData(authMessages.Dequeue()); } while (_tcpRunning) { readBytes = await networkStream.ReadAsync(buffer, 0, buffer.Length, _shutdownTokenSource.Token); if (readBytes > 0) { NetMessage.GetMessages(buffer, readBytes, ref bytesReceived, ref dataBuffer, ref lengthBuffer, ref bufferSize, player.ConsumeData); } if (!client.Connected) { return; } } } } catch (OperationCanceledException o) { Debug.Log("Operation canceled"); } catch (ObjectDisposedException ode) { if (_tcpRunning && ode.ObjectName != "System.Net.Sockets.NetworkStream") { Debug.LogException(ode, "{0} disposed when it shouldn't have", ode.ObjectName); } } catch (SocketException se) { } catch (IOException ioe) { if (!(ioe.InnerException is SocketException)) { Debug.LogException(ioe); } } catch (Exception exp) { Debug.LogException(exp); } finally { player.Status = ConnectionStatus.Disconnecting; Debug.Log("Closing client connection to {0}", endpoint); client.Close(); if (player != null) { player.Status = ConnectionStatus.Disconnected; RemovePlayer(player); player.NetworkStream = null; } } }
private async void HandleClientConnection(TcpClient client) { var endpoint = client.Client.RemoteEndPoint; Debug.Log($"Player connection request from {endpoint}"); client.ReceiveBufferSize = 1024; client.ReceiveTimeout = 5000; client.SendBufferSize = 1024; client.NoDelay = true; client.LingerState = new LingerOption(true, 10); ConnectionInfo ci = null; try { using (var networkStream = client.GetStream()) { var buffer = new byte[1024]; NetMessage dataBuffer = null; var bufferSize = 0; var lengthBuffer = new byte[2]; var bytesReceived = 0; int readBytes; var authMessages = new Queue <NetMessage>(); while (_tcpRunning) { readBytes = await networkStream.ReadAsync(buffer, 0, buffer.Length, _shutdownTokenSource.Token); if (readBytes > 0) { var readMessage = NetMessage.GetMessages(buffer, readBytes, ref bytesReceived, ref dataBuffer, ref lengthBuffer, ref bufferSize, authMessages.Enqueue); if (readMessage >= 1) { break; } } if (!client.Connected) { return; } } ci = new ConnectionInfo { Client = client, Stream = networkStream }; lock (_players) _players.Add(ci); if (authMessages.Count > 0) { PlayerAttemptingConnection(ci, (IPEndPoint)client.Client.RemoteEndPoint, player => { ci.Player = player; player.Status = ConnectionStatus.Connecting; }, authMessages.Dequeue()); } else { ci.Player.Disconnect("No authentication message sent"); } var canConnect = await ci.AllowConnectCompletion.Task; if (!canConnect) { return; } ci.Player.Status = ConnectionStatus.Connected; FinalizePlayerAdd(ci.Player); Debug.Log($"Client connected from {client.Client.RemoteEndPoint}"); //and drain the rest of messages that might have come after the auth while (authMessages.Count > 0) { ci.Player.ConsumeData(authMessages.Dequeue()); } while (_tcpRunning) { readBytes = await networkStream.ReadAsync(buffer, 0, buffer.Length, _shutdownTokenSource.Token); if (readBytes > 0) { NetMessage.GetMessages(buffer, readBytes, ref bytesReceived, ref dataBuffer, ref lengthBuffer, ref bufferSize, ci.Player.ConsumeData); } else { EnsureConnected(ci); } if (!client.Connected) { return; } } } } catch (OperationCanceledException o) { Debug.Log("Operation canceled"); } catch (ObjectDisposedException ode) { if (_tcpRunning && !ode.ObjectName.StartsWith("System.Net.Sockets")) { Debug.LogException(ode, $"{ode.ObjectName} disposed when it shouldn't have"); } } catch (SocketException se) { } catch (IOException ioe) { if (!(ioe.InnerException is SocketException)) { Debug.LogException(ioe); } } catch (Exception exp) { Debug.LogException(exp); } finally { Debug.Log($"Closing client connection to {endpoint}"); client.Close(); if (ci != null) { ci.Player.Status = ConnectionStatus.Disconnecting; lock (_players) _players.Remove(ci); ci.Player.Status = ConnectionStatus.Disconnected; RemovePlayer(ci.Player); ci.Player.Connection = null; } } }