tutorial socket servidor programacion hilos crear conexion conectar con comunicacion computadoras cliente java multithreading model-view-controller client

socket - Servidor Java con comunicación Multicliente.



sockets java (2)

Estoy haciendo un juego para una tarea. Tengo un servidor y multicliente configurado en Java y estamos usando MVC. Necesito que un cliente envíe su nombre al servidor y luego, cuando haya dos jugadores, necesito devolverles ambos nombres a los clientes junto con el número de jugador que son (jugador uno o jugador dos). No entiendo cómo podría decir de qué hilo proviene la información o a qué hilo se está enviando la información para que no todos los jugadores piensen que son el jugador uno. Gracias.


Aquí te comparto un buen programa de chat que tiene un servidor que se comunica con múltiples clientes usando el protocolo TCP según tu requerimiento.

El programa contiene:

  • Cada cliente es informado siempre que se agrega un nuevo cliente junto con su nombre y posición.
  • También verifica los nombres existentes. El programa no permite que múltiples clientes usen el mismo nombre.

Utiliza este programa como el inicio inicial de tu juego. Avíseme si desea agregar nuevas funcionalidades en el programa.

Aquí está el código (vea los comentarios del código para más aclaraciones):

Nota: reemplace el nombre del host en el archivo LiveChatClient.java antes de ejecutar este programa en el puerto n. ° 1234

Pasos para ejecutar el programa:

  • primero ejecuta LiveChatServer solo por una sola vez
  • luego ejecuta LiveChatClient para múltiples clientes tantos como quieras agregar

Opcode.java:

Código de operación que se usa para establecer un protocolo de comunicación cliente-servidor

package com.chat; /**************** an interface to define different operation code **************/ public interface Opcode { int CLIENT_CONNECTEING = 1; int CLIENT_CONNECTED = 2; }

LiveChatServer.java:

Servidor único que controla múltiples clientes

package com.chat; /************************ Live Chat Server *******************/ import java.io.IOException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.HashMap; import java.util.LinkedHashMap; public class LiveChatServer { // Connection state info private static LinkedHashMap<String, ClientThread> clientInfo = new LinkedHashMap<String, ClientThread>(); // TCP Components private ServerSocket serverSocket; // Main Constructor public LiveChatServer() { startServer();// start the server } public void startServer() { String port = "1234"; try { // in constractor we are passing port no, back log and bind address whick will be local // host // port no - the specified port, or 0 to use any free port. // backlog - the maximum length of the queue. use default if it is equal or less than 0 // bindAddr - the local InetAddress the server will bind to int portNo = Integer.valueOf(port); serverSocket = new ServerSocket(portNo, 0, InetAddress.getLocalHost()); System.out.println(serverSocket); System.out.println(serverSocket.getInetAddress().getHostName() + ":" + serverSocket.getLocalPort()); while (true) { Socket socket = serverSocket.accept(); new ClientThread(socket); } } catch (IOException e) { System.out.println("IO Exception:" + e); System.exit(1); } catch (NumberFormatException e) { System.out.println("Number Format Exception:" + e); System.exit(1); } } public static HashMap<String, ClientThread> getClientInfo() { return clientInfo; } // *********************************** Main Method ******************** public static void main(String args[]) { new LiveChatServer(); } }

LiveChatClient.java:

Múltiples clientes que hablan entre sí a través del servidor

package com.chat; /************************ Live Chat Client *******************/ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.InetAddress; import java.net.Socket; import java.net.SocketException; public class LiveChatClient { private String chatName;// current user''s chat name(max 7 char if greater than show as 6 // char+... private String serverAddress; // TCP Components private Socket socket; private BufferedReader in; private PrintWriter out; public LiveChatClient() { initHostName(); runClient();// have fun } public void initHostName() { try { //replace host name with your computer name or IP address serverAddress = "[hostname]"; if (serverAddress == null) System.exit(1); serverAddress = serverAddress.trim(); if (serverAddress.length() == 0)// empty field { System.out.println("Server IP Address or Name can''t be blank."); initHostName(); return; } System.out.println("Trying to connect with server.../nServer IP Address:" + serverAddress); // create socket InetAddress inetAddress = InetAddress.getByName(serverAddress); if (!inetAddress.isReachable(60000))// 60 sec { System.out .println("Error! Unable to connect with server./nServer IP Address may be wrong."); System.exit(1); } initPortNo(); } catch (SocketException e) { System.out.println("Socket Exception:/n" + e); initHostName(); return; } catch (IOException e) { initHostName(); return; } } public void initPortNo() { try { String portNo = "1234"; portNo = portNo.trim(); if (portNo.length() == 0)// empty field { System.out.println("Server port No can''t be blank."); initPortNo(); return; } System.out.println("Trying to connect with server.../nServer Port No:" + portNo); socket = new Socket(serverAddress, 1234); in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(), true); } catch (IOException e) { System.out.println("IO Exception:/n" + e); initPortNo(); return; } } public void sendChatName() throws IOException { System.out.println("Enter your name:"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String name = br.readLine(); if (name == null) System.exit(1); // title case (get only first 9 chars of chat name) name = name.trim(); if (name.equalsIgnoreCase("All")) { System.out.println("This name is already reserved. Try different one."); sendChatName(); return; } if (name.length() == 0) { System.out.println("Please enter your chat name."); sendChatName(); return; } if (name.length() == 1) chatName = String.valueOf(name.charAt(0)).toUpperCase(); if (name.length() > 1 && name.length() < 10) chatName = String.valueOf(name.charAt(0)).toUpperCase() + name.substring(1).toLowerCase(); else if (name.length() > 9) chatName = String.valueOf(name.charAt(0)).toUpperCase() + name.substring(1, 10).toLowerCase(); // sending opcode first then sending chatName to the server out.println(Opcode.CLIENT_CONNECTEING); out.println(chatName); } public void runClient() { try { sendChatName(); while (true) { int opcode = Integer.parseInt(in.readLine()); switch (opcode) { case Opcode.CLIENT_CONNECTEING: // this client is connecting boolean result = Boolean.valueOf(in.readLine()); if (result) { System.out .println(chatName + " is already present. Try different one."); runClient(); } break; case Opcode.CLIENT_CONNECTED: // a new client is connected Integer totalClient = Integer.valueOf(in.readLine()); System.out.println("Total Client:" + totalClient); for (int i = 0; i < totalClient; i++) { String client = in.readLine(); System.out.println((i + 1) + ":" + client); } break; } } } catch (IOException e) { System.out.println("Client is closed..."); } } // *********************************** Main Method ******************** public static void main(String args[]) { new LiveChatClient(); } }

ClientThread.java:

Múltiples hilos iniciados por el servidor uno para cada cliente y que contienen información sobre todos los clientes conectados

package com.chat; /************************ Client Thread *******************/ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.util.HashMap; public class ClientThread implements Runnable { // TCP Components private Socket socket; private BufferedReader in; private PrintWriter out; private String chatName; // seperate thread private Thread thread; // boolean variable to check that client is running or not private volatile boolean isRunning = true; // opcode private int opcode; private HashMap<String, ClientThread> clientInfo = new HashMap<String, ClientThread>(); public ClientThread(Socket socket) { try { this.socket = socket; this.clientInfo = LiveChatServer.getClientInfo(); in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(), true); thread = new Thread(this); thread.start(); } catch (IOException e) { System.out.println(e); } } public void run() { try { while (isRunning) { if (!in.ready()) continue; opcode = Integer.parseInt(in.readLine());// getting opcode first from client switch (opcode) { case Opcode.CLIENT_CONNECTEING: chatName = in.readLine(); boolean result = clientInfo.containsKey(chatName); out.println(Opcode.CLIENT_CONNECTEING); out.println(result); if (result)// wait for another chat name if already present continue; // send list of already online users to new online user // for (Object user : clientInfo.keySet().toArray()) { // out.println(Opcode.CLIENT_CONNECTED); // out.println(user.toString()); // } // put new entry in clientInfo hashmap clientInfo.put(chatName, this); int i = 0; for (String key : clientInfo.keySet()) { if (key.equals(chatName)) { System.out.println(chatName + " added at " + (i + 1) + " position"); } i++; } // tell other users about new added user and update their online users list for (ClientThread client : clientInfo.values()) { client.out.println(Opcode.CLIENT_CONNECTED); client.out.println(clientInfo.size()); for (ClientThread client1 : clientInfo.values()) { client.out.println(client1.chatName); } } break; } } // clsoe all connections out.close(); in.close(); socket.close(); } catch (IOException e) { System.out.println(e); } } }

Aquí está el resultado cuando se agregan dos clientes.

Servidor:

ServerSocket[addr=computerName/IPAddress,port=0,localport=1234] computerName:1234 Abc added at 1 position Xyz added at 2 position

Cliente 1:

Trying to connect with server... Server IP Address:computerName Trying to connect with server... Server Port No:1234 Enter your name: abc Total Client:1 1:Abc Total Client:2 1:Abc 2:Xyz

Cliente 2:

Trying to connect with server... Server IP Address:computerName Trying to connect with server... Server Port No:1234 Enter your name: xyz Total Client:2 1:Abc 2:Xyz


Tener 2 hilos, uno para el usuario 1 y otro para el usuario 2. Deben comunicarse entre ellos utilizando un objeto compartido y notificarse entre sí cuando ocurran los eventos. Engendre el hilo 1 cuando el primer usuario se conecta y engendra el hilo 2 cuando se conecta el segundo usuario.