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