server and client game hangs when i send data

Hi guys, im doing a kind of game using TCP sockets.

i have to say that i dont know best practices with TCP or UDP, so sugestions would be apreciated…

i have a SERVER
{

when the object is created:

#1 start a thread where the server accepts incoming connections
#2 when a client is connected an id is created and sent to client
#3 the client recive the new ID and then this id is stored by the client
#4 after the the ID is tored, this send a command to the server that indicate: create a new player
#5 then the server create a new player and send a response to all the clients
#6 all the clients recive the response to create the player
#7 all the players are shown in the canvas client, like a list, just the player name
#8
#9
#10

well thats thats the idea of the functionality.

THE PROBLEM IS THAT THE SERVER HANGS,
I JUST CAN CREATE THE PLAYER OF 1 CLIENT THEN THE LOOP IS STOPPED AND I CANT FIND
WHERE IS THE ERROR.

Here is the code:

CLIENT CODE


public class Looby extends GameLevel
{
    
    //variables del jugador 
    String playerName;
    String playerclass;
    List<NtwSprite> playerPool; 
    DataInputStream response;
    DataOutputStream request;
    
    
    /**
     * constructor 1
     * @param roomWidth
     * @param roomHeight
     * @param viewWidth
     * @param viewHeight
     * @param imgbg 
     */
    public Looby(int roomWidth, int roomHeight, int viewWidth, int viewHeight,
           ArrayList<ImageBackground> imgbg)
    {
    super(roomWidth, roomHeight, viewWidth, viewHeight, imgbg);
    }//const 1

@Override
    public void update()  ///update is the method who is executed by the game loop
    {
        System.out.println("UPDATING CLIENT");
        
        try {
//the gameState is managed in other objetc, but generally is the state PLAYING
            switch(gameState)
            {
                case LOADING:
                    break;
                case PLAYING:

//this method manages all the input and output data of the comunications between sockets
                    manageNetworkData();
                    break;
            }//suich
        } catch (IOException ex) {
            System.out.println("Error en update client LOBBY");
            ex.printStackTrace();
        }
    }

@Override
    public void renderHUD(Graphics g) 
    {
    
       Graphics2D g2 =  (Graphics2D)g;
       g2.drawString("LOOBY", roomWidth/2,  roomWidth/2-10);
       switch(gameState)
       {
           case LOADING:
               
//               Graphics2D g2 =  (Graphics2D)g;
               
               g2.setColor(Color.BLACK);
               g2.fillRect(0, 0, roomWidth,roomHeight);
               
               g2.setColor(Color.white);
               g2.drawString("CARGANDO...", roomWidth/2, roomHeight/2);
               
               
               break;
           case PLAYING:
               
//               Graphics2D gg2 =  (Graphics2D)g;
               
               g2.setColor(Color.GRAY);
               g2.fillRect(0, 0, roomWidth,roomHeight);
               
               g2.setColor(Color.BLACK);
               g2.drawString("Jugadores conectados:", 20,20);
               
               for (int i = 0; i < playerPool.size(); i++)
               {
                   NtwSprite ntspr =playerPool.get(i);
                   if(ntspr !=null)
                   {
//                 g2.drawString("name: "+ntspr.getUsername()+" class: "+ntspr.getUserclass(), 20*(i+2),20);
                   g2.drawString("name: "+ntspr.getUsername()+" class: Knight", 20,20*(i+2));
                   }//
               }//
               
               break;
           
       }//
       
       
    }//

    @Override
    public synchronized void manageNetworkData() throws IOException 
    {
            String [] responsemsg = Communication.splitData(getRoom().getGameClient().getMessage());
            
            switch(responsemsg[0])
            {
                case ServerGameState.SETID:
                    //se le pone el clientId a este socket 
                    room.getGameClient().setClientId(responsemsg[1]);
                    String request = "initplayer:men";
                    break;
                case ServerGameState.CREATEPLAYER:
                    //crear el sprite
                    //sacar el ID que envia el server y agregarlo al sprite
                    NtwSprite player = new NtwSprite(getRoom().getGameClient().getClientId(), responsemsg[1]);
                    playerPool.add(player);
                    break;
            
            }//
        
    }//managentw



public class ServerManagerLevel extends GameLevel
{
 
    List<NtwSprite> playerPool;
    List<String> responses;
    
    public ServerManagerLevel(int roomWidth, int roomHeight,int viewWidth,int viewHeight,ArrayList<ImageBackground> imgbg)
    {
        // se crea el constructor
        super(roomWidth, roomHeight, viewWidth, viewHeight, imgbg);
        playerPool = new ArrayList<>();
        responses = new ArrayList<>();
        
    }//const

    @Override
    public void update() 
    {
        
          switch(gameState)
            {
                case LOADING:
                    System.out.println("SERVER LOADING");
                    break;
                case PLAYING:
                    System.out.println("SERVER PLAYING");
//              #1 se procesan todas las peticiones aqui
              try {
                  System.out.println("EJECUTANDO MANAGENETWORK DATA SERVER");
                  manageNetworkData();
              } catch (IOException ex) {
                  System.out.println("Error en managentwdata de SERVER");
                  ex.printStackTrace();
              }
          
        for(ClientSocket client: this.room.getGameServer().getClients())
        {
            for(String s: responses)
            {
                try {
                    client.sendMessage(s);
                    //Communication.sendData(client.getSocket(), s);
                } catch (IOException ex) {
                    System.out.println("Error en A");}
                
            }//for responses
        }//for
        
                    break;
                    
            }//suich        
    }//update

@Override
    public synchronized void manageNetworkData() throws IOException 
    {
 
        for(ClientSocket client: this.room.getGameServer().getClients())
        {
              
              String[] request = Communication.splitData(client.getMessage());
              System.out.println("ANTES DEL SUCICH");  
              switch(request[0])
              {
              
                  case "initplayer":
                      NtwSprite player = new NtwSprite(client.getClientId() ,request[1]);
                      playerPool.add(player);
                      responses.add(ServerGameState.CREATEPLAYER+":"+player.getUsername());
                      break;
              }//suich
              
        }//for
       
    }//managenetworkdata


well, if you need to understand well the code, let me know, i think the server hangs because its sending constantly some request request

this is the class of the server:



/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package net;

import Config.ServerGameState;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * clase que tiene metodos estaticos para enviar o recibir datos entre sockets
 * @author pavulzavala
 */
public class Server implements Runnable
{
 
    private final int SLEEPTIME=5000; //segundos que duerme el thread
    
    private ServerSocket gameServer; //socket servidor
    private List<ClientSocket> clients; //listado de clientes conectados
    
    private String ip; //ip del servidor
    private int port; //puerto del servidor
    private int maxConnections; //numero de conexiones maximas que puede aceptar el server
    
    
    private Thread thread;
    private boolean isRunning;
    
   /**
    * constructor 1 que instancia el server socket en el puerto dado
    * @param port 
     * @throws java.io.IOException 
    */
    public Server(int port) throws IOException
    {
        this.port=port;
        clients = new ArrayList<>();
        gameServer = new ServerSocket(port);
        thread = new Thread(this);
        thread.start();
    }//const1
    
    /**
     * cnostructor 2 donde se indica el puerto que escuchara el server
     * y el numero de maximo de conecciones que se pueden hacer
     * @param port
     * @param maxConnections
     * @throws IOException 
     */
     public Server(int port, int maxConnections) throws IOException
    {
        this(port);
        this.maxConnections= maxConnections;
    }//const1
    
    /**
     * metodo que inserta el cliente conectado al arraylist de clientes
     * y regresa true si fue exitoso
     * @return 
     * @throws java.io.IOException 
     */
    public boolean connectClient() 
    {
        try {
            //se agrega el socket del cliente conectado a la lista
            ClientSocket client = new ClientSocket(gameServer.accept());
            
            System.out.println("ANTES DE ENVIAR A CLIENTEID: "+client.getClientId());
            
            clients.add(client);
            //se envia en respuesta al cliente el ID que le creo el server
            Communication.sendData(client.getSocket(), ServerGameState.SETID+":"+client.getClientId());
            
            System.out.println("Cliente conectado:: "+client.getSocket().getInetAddress().toString());
            System.out.println("( clients.size() ) numeros de clientes que tiene el servidor: "+clients.size());
            
            
        } catch (IOException ex) {
            System.out.println("Error en B");
            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
        return true;
    }//connect
    
    
    /**
     * funcion que regresa los cleintes conectados al servidor
     * @return 
     */
    public int getConnectedClients()
    {
        if(clients == null)return 0;
        return clients.size();
    }//
    
    /**
     * funcion que checa si algun cliente ya no esta conectado y lo remueve de la lista
     * de clientes
     */
    public void removeDisconectedClients()
    {
    
        for(int i = 0; i < clients.size(); i++) 
        {
            if(!clients.get(i).getSocket().isConnected() )
            {
            clients.remove(i);
            }
        }//
        
    }//remove
    
   
    /**
     * funcion que cierra el socket del cliente y lo remueve de la lista de
     * clientes conectados, en caso de checar que ya no hay coneccion con dicho cliente
     * o simplemente si se le quiere forzar el cierre de la conneccion
     * @param clientId 
     * @return  
     * @throws java.io.IOException 
     */
     public boolean removeDisconectedClient(String clientId) throws IOException
    {
    
        for(int i = 0; i < clients.size(); i++) 
        {
            if(!clients.get(i).getSocket().isConnected() && clients.get(i).getClientId().equals(clientId) )
            {
                //primero se cierra el socket y posteriormente se remueve de la lista
                clients.get(i).getSocket().close();
                clients.remove(i);
                return true;
            }
            
        }//
        return false;
    }//remove
    
    
    

    public List<ClientSocket> getClients() {
        return clients;
    }

    public void setClients(List<ClientSocket> clients) {
        this.clients = clients;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    @Override
    public void run() 
    {
        isRunning=true;
        
        while(isRunning)
        { 
            System.out.println(" aceptando conecciones: "+isRunning);
            //se conectan cleintes periodicamente
                connectClient();
            
        }//while
        
        try {
                Thread.sleep(SLEEPTIME);
            } //while
            catch (InterruptedException ex) {
                System.out.println("Error Server.java InterruptedException");
            }
            catch(Exception e)
            {
                System.out.println("Error Server.java Exception");
            }
        
    }//run
    
   
    
    
}//class



You don’t show code how the instance of Server is used after creation, but in its current state, your Server.run() function doesn’t make any sense anyway.

There is no exit condition in your “while (isRunning)” loop. It calls connectClient(), which will block infinitely at gameServer.accept(). This means that this thread just sits there, waiting, until another client tries to connect.

but it works the fist time,

GameServer is created in another class that init all components, basically the clases i shown, are the levels or screens, those levels are displayed in a canvas, thats where the GameServer its instanciated,

the class of the canvas has its own gameloop, and then when GameServer is created it creates an instance of Server, that means that the Server class accepts connections in separate threads, as i said before, the thread only hangs after the first connection has been done, i tried to connect another client after that and its connected as well, but it doesnt send the initial data

by the way i know i dont have a strong structure, but that its what i need to figure, im dummie using sockets, thats why i need help XD