/// <summary> /// Recibir información inicial del cliente /// </summary> /// <returns>True si todo salio bien</returns> private bool getClientInitialInfo(TgcSocketClientInfo clientInfo, Socket socket) { try { //Recibir info inicial del cliente TgcSocketRecvMsg msg = TgcSocketMessages.receiveMessage(socket, TgcSocketMessageHeader.MsgType.InitialMessage); if (msg == null) { return(false); } //Guardar sus datos y cambiar su estado TgcSocketInitialInfoClient clientInitInfo = (TgcSocketInitialInfoClient)msg.readNext(); clientInfo.Name = clientInitInfo.clientName; clientInfo.Status = TgcSocketClientInfo.ClientStatus.WaitingClientOk; //Asignar Player ID a cliente TgcSocketInitialInfoServer serverInitInfo = new TgcSocketInitialInfoServer(); serverInitInfo.serverName = serverName; serverInitInfo.playerId = playerIdCounter; clientInfo.PlayerId = serverInitInfo.playerId; playerIdCounter++; //Enviar info inicial del server TgcSocketSendMsg sendMsg = new TgcSocketSendMsg(); sendMsg.write(serverInitInfo); TgcSocketMessages.sendMessage(socket, sendMsg, TgcSocketMessageHeader.MsgType.InitialMessage); return(true); } catch (SocketException) { return(false); } }
/// <summary> /// Enviar mensaje a cliente, solo si esta conectado /// </summary> private void sendToClient(TgcSocketClientInfo clientInfo, TgcSocketSendMsg msg) { if (clientInfo.Status == TgcSocketClientInfo.ClientStatus.Connected) { TgcSocketMessages.sendMessage(clientInfo.Socket, msg, TgcSocketMessageHeader.MsgType.RegularMessage); } }
/// <summary> /// Recibir la confirmación final del cliente para empezar a recibir mensajes de la aplicación /// </summary> /// <returns>True si todo salio bien</returns> private bool getClientOkResponse(TgcSocketClientInfo clientInfo, Socket socket) { try { //Recibir respuesta final del cliente TgcSocketRecvMsg msg = TgcSocketMessages.receiveMessage(socket, TgcSocketMessageHeader.MsgType.InitialMessage); if (msg == null) { return(false); } //Respuesta del cliente //bool userOk = bool.Parse(msg.readString()); bool userOk = (bool)msg.readNext(); if (userOk) { //Habilitar estado de cliente para escuchar mensajes clientInfo.Status = TgcSocketClientInfo.ClientStatus.Connected; connectedClients.Add(clientInfo); //Guardar en la lista de nuevos clientes conectados newConnectedClients.Enqueue(clientInfo); } return(userOk); } catch (SocketException) { return(false); } }
/// <summary> /// Atender nuevas conexiones de clientes /// </summary> private void acceptNewClients() { //Ver si hay alguna conexion pendiente if (serverSocket.Poll(0, SelectMode.SelectRead)) { //Aceptar nuevo cliente Socket clientSocket = serverSocket.Accept(); //Ver si es un tipo de conexion valido if (clientSocket.AddressFamily == AddressFamily.InterNetwork && clientSocket.SocketType == SocketType.Stream && clientSocket.ProtocolType == ProtocolType.Tcp) { //Agrear cliente válido a la lista TgcSocketClientInfo clientInfo = new TgcSocketClientInfo(clientSocket); allClients.Add(clientInfo); } //Si no es válido, desconectar else { try { clientSocket.Shutdown(SocketShutdown.Both); clientSocket.Close(); } catch (Exception) { } } } }
/// <summary> /// Hacer Handshake con el cliente para ver si es un cliente correcto /// </summary> /// <returns>True si todo salio bien</returns> private bool doHandshake(TgcSocketClientInfo clientInfo, Socket socket) { try { int clientHandshakeLength = Encoding.ASCII.GetBytes(TgcSocketClient.CLIENT_HANDSHAKE).Length; byte[] data = new byte[clientHandshakeLength]; int recv = socket.Receive(data, data.Length, SocketFlags.None); if (recv > 0 && recv == clientHandshakeLength) { string msg = Encoding.ASCII.GetString(data, 0, recv); if (msg.Equals(TgcSocketClient.CLIENT_HANDSHAKE)) { //Cliente aceptado, falta recibir datos iniciales clientInfo.Status = TgcSocketClientInfo.ClientStatus.RequireInitialInfo; //Enviar respuesta de handshake socket.Send(Encoding.ASCII.GetBytes(SERVER_HANDSHAKE)); return(true); } } } catch (SocketException) { //Handshake incorrecto return(false); } return(false); }
private void updateServer() { if (server.Online) { server.updateNetwork(); //Nuevos clientes conectados, leer sin consumir newConnectedClients.Clear(); for (int i = 0; i < server.NewClientsCount; i++) { TgcSocketClientInfo clientInfo = server.nextNewClient(); newConnectedClients.Enqueue(clientInfo); networkingControl.addClient(clientInfo); } //Clientes desconectados disconnectedClients.Clear(); for (int i = 0; i < server.DisconnectedClientsCount; i++) { TgcSocketClientInfo clientInfo = server.nextDisconnectedClient(); disconnectedClients.Enqueue(clientInfo); networkingControl.onClientDisconnected(clientInfo); } } }
/// <summary> /// Envia un mensaje a un cliente particular /// </summary> /// <param name="playerId">ID del cliente</param> /// <param name="msg">Mensaje a enviar</param> public void sendToClient(int playerId, TgcSocketSendMsg msg) { TgcSocketClientInfo clientInfo = getClientInfo(playerId); if (clientInfo != null) { sendToClient(clientInfo, msg); } }
/// <summary> /// Agregar un cliente a la lista de conectados /// </summary> internal void addClient(TgcSocketClientInfo clientInfo) { dataGridViewConnectedClients.Rows.Add(dataGridViewConnectedClients.Rows.Count, clientInfo.PlayerId, clientInfo.Name, clientInfo.Address.ToString()); //seleccionar el primer elemento de la tabla dataGridViewConnectedClients.Rows[0].Selected = true; dataGridViewConnectedClients_RowEnter(null, null); }
/// <summary> /// Desconectar a un cliente particular del servidor /// </summary> /// <param name="playerId">ID del cliente a desconectar</param> public void disconnectClient(int playerId) { TgcSocketClientInfo clientInfo = getClientInfo(playerId); if (clientInfo != null) { allClients.Remove(clientInfo); connectedClients.Remove(clientInfo); try { clientInfo.Socket.Shutdown(SocketShutdown.Both); clientInfo.Socket.Close(); } catch (Exception) { } } }
/// <summary> /// Lee un mensaje ordinario recibido por el cliente /// </summary> /// <returns>True si todo salio bien</returns> private bool getReceiveMessage(TgcSocketClientInfo clientInfo, Socket socket) { try { //Recibir mensaje TgcSocketRecvMsg msg = TgcSocketMessages.receiveMessage(socket, TgcSocketMessageHeader.MsgType.RegularMessage); if (msg == null) { return(false); } //Agregar a la lista de mensajes pendientes receivedMessages.Enqueue(new TgcSocketClientRecvMesg(msg, clientInfo.PlayerId)); return(true); } catch (Exception) { return(false); } }
/// <summary> /// Eliminar un cliente conectado de la lista que se acaba de desconectar /// </summary> internal void onClientDisconnected(TgcSocketClientInfo clientInfo) { for (int i = 0; i < dataGridViewConnectedClients.Rows.Count; i++) { int rowPlayerId = (int)dataGridViewConnectedClients.Rows[i].Cells[1].Value; if (rowPlayerId == clientInfo.PlayerId) { dataGridViewConnectedClients.Rows.RemoveAt(i); break; } } //Ver que quedo en la tabla if (dataGridViewConnectedClients.Rows.Count > 0) { dataGridViewConnectedClients.Rows[0].Selected = true; dataGridViewConnectedClients_RowEnter(null, null); } else { buttonDeleteClient.Enabled = false; } }
/// <summary> /// Eliminar un cliente conectado de la lista que se acaba de desconectar /// </summary> internal void onClientDisconnected(TgcSocketClientInfo clientInfo) { //Si la ventana de clientes estaba abierta, cerrarla primero, para que no haya lio de Threas de refresco clientsDialog.Hide(); clientsDialog.onClientDisconnected(clientInfo); }
/// <summary> /// Agregar un cliente a la lista de conectados /// </summary> internal void addClient(TgcSocketClientInfo clientInfo) { clientsDialog.addClient(clientInfo); }
/// <summary> /// Recibir información inicial del cliente /// </summary> /// <returns>True si todo salio bien</returns> private bool getClientInitialInfo(TgcSocketClientInfo clientInfo, Socket socket) { try { //Recibir info inicial del cliente TgcSocketRecvMsg msg = TgcSocketMessages.receiveMessage(socket, TgcSocketMessageHeader.MsgType.InitialMessage); if (msg == null) { return false; } //Guardar sus datos y cambiar su estado TgcSocketInitialInfoClient clientInitInfo = (TgcSocketInitialInfoClient)msg.readNext(); clientInfo.Name = clientInitInfo.clientName; clientInfo.Status = TgcSocketClientInfo.ClientStatus.WaitingClientOk; //Asignar Player ID a cliente TgcSocketInitialInfoServer serverInitInfo = new TgcSocketInitialInfoServer(); serverInitInfo.serverName = serverName; serverInitInfo.playerId = playerIdCounter; clientInfo.PlayerId = serverInitInfo.playerId; playerIdCounter++; //Enviar info inicial del server TgcSocketSendMsg sendMsg = new TgcSocketSendMsg(); sendMsg.write(serverInitInfo); TgcSocketMessages.sendMessage(socket, sendMsg, TgcSocketMessageHeader.MsgType.InitialMessage); return true; } catch (SocketException) { return false; } }
/// <summary> /// Hacer Handshake con el cliente para ver si es un cliente correcto /// </summary> /// <returns>True si todo salio bien</returns> private bool doHandshake(TgcSocketClientInfo clientInfo, Socket socket) { try { int clientHandshakeLength = Encoding.ASCII.GetBytes(TgcSocketClient.CLIENT_HANDSHAKE).Length; byte[] data = new byte[clientHandshakeLength]; int recv = socket.Receive(data, data.Length, SocketFlags.None); if (recv > 0 && recv == clientHandshakeLength) { string msg = Encoding.ASCII.GetString(data, 0, recv); if (msg.Equals(TgcSocketClient.CLIENT_HANDSHAKE)) { //Cliente aceptado, falta recibir datos iniciales clientInfo.Status = TgcSocketClientInfo.ClientStatus.RequireInitialInfo; //Enviar respuesta de handshake socket.Send(Encoding.ASCII.GetBytes(SERVER_HANDSHAKE)); return true; } } } catch (SocketException) { //Handshake incorrecto return false; } return false; }
/// <summary> /// Recibir la confirmación final del cliente para empezar a recibir mensajes de la aplicación /// </summary> /// <returns>True si todo salio bien</returns> private bool getClientOkResponse(TgcSocketClientInfo clientInfo, Socket socket) { try { //Recibir respuesta final del cliente TgcSocketRecvMsg msg = TgcSocketMessages.receiveMessage(socket, TgcSocketMessageHeader.MsgType.InitialMessage); if (msg == null) { return false; } //Respuesta del cliente //bool userOk = bool.Parse(msg.readString()); bool userOk = (bool)msg.readNext(); if (userOk) { //Habilitar estado de cliente para escuchar mensajes clientInfo.Status = TgcSocketClientInfo.ClientStatus.Connected; connectedClients.Add(clientInfo); //Guardar en la lista de nuevos clientes conectados newConnectedClients.Enqueue(clientInfo); } return userOk; } catch (SocketException) { return false; } }
/// <summary> /// Lee un mensaje ordinario recibido por el cliente /// </summary> /// <returns>True si todo salio bien</returns> private bool getReceiveMessage(TgcSocketClientInfo clientInfo, Socket socket) { try { //Recibir mensaje TgcSocketRecvMsg msg = TgcSocketMessages.receiveMessage(socket, TgcSocketMessageHeader.MsgType.RegularMessage); if (msg == null) { return false; } //Agregar a la lista de mensajes pendientes receivedMessages.Enqueue(new TgcSocketClientRecvMesg(msg, clientInfo.PlayerId)); return true; } catch (Exception) { return false; } }
/// <summary> /// Recibe todos los mensajes pendientes de la red y actualiza todos los estados /// </summary> public void updateNetwork() { //Escuchar nuevas conexiones acceptNewClients(); //Recibir mensajes de clientes for (int i = 0; i < allClients.Count; i++) { TgcSocketClientInfo clientInfo = allClients[i]; Socket socket = clientInfo.Socket; //Ver si envió algún mensaje if (socket.Poll(0, SelectMode.SelectRead)) { bool result; switch (clientInfo.Status) { //Handshake para clientes pendientes de aprobación case TgcSocketClientInfo.ClientStatus.HandshakePending: result = doHandshake(clientInfo, socket); if (!result) { //Handshake incorrecto, eliminar cliente allClients.RemoveAt(i); i--; } break; //Recibir información inicial del cliente case TgcSocketClientInfo.ClientStatus.RequireInitialInfo: result = getClientInitialInfo(clientInfo, socket); if (!result) { //Error al recibir información inicial, eliminar cliente allClients.RemoveAt(i); i--; } break; //Recibir aprobación final del cliente case TgcSocketClientInfo.ClientStatus.WaitingClientOk: result = getClientOkResponse(clientInfo, socket); if (!result) { //El cliente no aceptó la conexión, eliminar allClients.RemoveAt(i); i--; } break; //Recibir mensajes de clientes ya aprobados case TgcSocketClientInfo.ClientStatus.Connected: result = getReceiveMessage(clientInfo, socket); if (!result) { //Si hubo algún problema entonces el cliente se desconectó, eliminar allClients.RemoveAt(i); connectedClients.Remove(clientInfo); i--; } break; } } } }