When creating multiple clients, I get one response from the server for each client and the program hangs on it. Tell me what's wrong. Thank you in advance

VServerThreads

public class VServerThreads { private static ServerSocket serverSocket = null; public static void main(String[] args) { try { try { serverSocket = new ServerSocket(2222); System.out.println("Initialized"); // waiting for a client while (true) { Socket socket = serverSocket.accept(); System.out.println(socket.getInetAddress().getHostAddress() + " connected"); // creating a new thread for a new client VServer vServer = new VServer(socket); new Thread(vServer).start(); } }finally { if(!serverSocket.isClosed()) { serverSocket.close(); } } } catch (IOException ex) { ex.printStackTrace(); } } } 

VServer

 class VServer extends Thread { private static Socket clientSocket = null; private static int userNumIncrement = 1; private int userNum = 0; private static DataInputStream in = null; private static DataOutputStream out = null; public VServer(Socket socket) throws IOException { clientSocket = socket; in = new DataInputStream(clientSocket.getInputStream()); out = new DataOutputStream(clientSocket.getOutputStream()); userNum = userNumIncrement; userNumIncrement++; } @Override public void run() { try { try { String line; while (true) { line = in.readUTF(); System.out.print("\nReceive from user " + userNum + ": " + line); if (line.startsWith("/quit")) { break; } System.out.print("\nI am sending it back for user num " + userNum + ": " + line); out.writeUTF(line); out.flush(); } out.writeUTF("*** Bye " + " ***"); } catch (IOException e) { e.printStackTrace(); } finally { in.close(); out.close(); clientSocket.close(); } } catch (IOException ex) { ex.printStackTrace(); } } public void disconnect() { try { System.out.println("Disconnected"); in.close(); out.close(); } catch (IOException ex) { ex.printStackTrace(); } finally { this.interrupt(); } } } 

Vclient

 public class VClient { private static Socket socket = null; private static DataInputStream in = null; private static DataOutputStream out = null; private static Scanner keyboard = null; public static void main(String[] args) { String address = "127.0.0.1"; try { InetAddress ipAddress = InetAddress.getByName(address); socket = new Socket(ipAddress, 2222); try { keyboard = new Scanner(System.in); in = new DataInputStream(socket.getInputStream()); out = new DataOutputStream(socket.getOutputStream()); String line; while(true) { line = keyboard.nextLine(); out.writeUTF(line); out.flush(); line = in.readUTF(); System.out.println("Waiting for the answer from the server"); System.out.println(line); if (line.contains("*** Bye")) break; } } finally { in.close(); out.close(); socket.close(); } } catch (IOException ex) { ex.printStackTrace(); } } } 

    1 answer 1

    Your fields of the VServer object servicing client connections are marked as static , i.e. they are common to all of these objects, and when a second client connects and a second VServer object is created, the data for the first is overwritten.

    On the little things:

    • vServer do not need to vServer into a new Thread , it is itself a heir of Thread (or rather, remove inheritance, implement Runnable and use the process pool ).
    • userNumIncrement better to make an AtomicInteger object, and use userNum = userNumIncrement.incrementAndGet() in the constructor. In your code, this is not critical, since VServer instances are created in only one process, but generally an increment is not an atomic operation, and several processes can assign the same userNum values ​​to different userNum .
    • To work with I / O streams in Java 7 and higher, it is advisable to use the try-with-resources construct. VServer.run() can be rewritten as follows:

       @Override public void run() { try ( // для всех объектов, реализующих AutoClosable, объявленных в этом блоке // будет вызван метод close(), после выхода из блока. Socket socket = this.clientSocket; DataInputStream in = new DataInputStream(socket.getInputStream() ); DataOutputStream out = new DataOutputStream(socket.getOutputStream()) ) { while ( !Thread.currentThread().isInterrupted() ) { String line = in.readUTF(); System.out.print("\nReceive from user " + userNum + ": " + line); if (line.startsWith("/quit")) { break; } System.out.print("\nI am sending it back for user num " + userNum + ": " + line); out.writeUTF(line); out.flush(); } out.writeUTF("*** Bye " + " ***"); } catch ( IOException ex ) { ex.printStackTrace(); } } 

      Thread fields can be removed, and in disconnect() call clientSocket.close()

    • Thank you very much. Everything works even better than I wanted) - merkan