I have a problem with a client/server in Java. It's a school project.
I open the sockets in my Java server with:
BufferedReader reader =
new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter writer =
new PrintWriter(new OutputStreamWriter(client.getOutputStream()), true);
and I open the sockets on the client side (4 client, 1 thread per client) with:
BufferedReader reader =
new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter writer =
new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
I get a synchronization error. Let me explain.
Server is sending in text "J1GO"
(which means "Player 1 go"
), to all clients, until Player 1 has ended the task. Then the variable change, and it sends "P2GO"
, but due to an obscure reason only client 1 (Player 1) gets the new text, and it takes 30 to 40 seconds until Players 2, 3, and 4 get the text. It's like if there was a bottleneck, or something. (Then, when it's Player 2's turn, it will take even longer!)
Edit:
Server side:
if (ligne.contains("Attente"))
{
writer.println("J"+Serveur.PlayerTurn+ "GO"); // (J1-2-3-4GO)
writer.flush();
Client side:
if (Deplacement)
{
sleep();
writer.println("Attente");
writer.flush();
String ligne = reader.readLine();
System.out.println(ligne);
int Coup = 99;
if (!Question)
{
if (!ligne.contains(IamPlayer +"GO")) //J1-2-3-4GO
{
sleep();
writer.println("Attente");
writer.flush();
}
else // go on...
I will explain how I do the exchange between the server. When the game starts, the server send "J1GO"
, to all clients, the Player1
client reads it, and start the game. Others clients read it, but they don't start the game, they send "Waiting..."
, when the server get a 开发者_C百科"Waiting.."
, he send a "J1GO"
, so when it's Player2
turn's, the server will send a J2GO
, so the Player2
will start the game, and Player1
will go back to waiting mode
Complete server side code:
import java.net.*;
import java.io.*;
public class Serveur
{
public static int NombreJoueurs = 1;
public static boolean Debut = false;
public static Joueur J1 = new Joueur();
public static Joueur J2 = new Joueur();
public static Joueur J3 = new Joueur();
public static Joueur J4 = new Joueur();
public static ConnectionBD BD = new ConnectionBD();
public static boolean Pret = false;
public static String TourJoueur = "1";
public static String NumeroQuestion = null;
public static boolean PretAJouer()
{
if (Pret)
Pret=false;
else
Pret = true;
return Pret;
}
public static void AjouterJoueur()
{
NombreJoueurs = NombreJoueurs+1;
}
public void servir( int port )
{
try
{
ServerSocket serveur = new ServerSocket( port );
System.out.println( "Serveur echo en ligne" );
System.out.println(Serveur.BD.VerifierReponse("V04B"));
boolean enService = true;
while ( enService )
{
Socket client = serveur.accept();
System.out.println( "Client connecte" );
// pour chaque nouvelle connexion on crée un thread qui prend en
// charge les échanges avec le client
Connexion connexion = new Connexion( client );
new Thread( connexion ).start();
}
}
catch ( Exception e )
{
System.err.println( e );
}
}
public static void main(String[] args)
{
new Serveur().servir( 1337 );
}
}
class Connexion implements Runnable
{
Socket client;
Connexion( Socket client )
{
this.client = client;
}
// thread qui s'occupe des échanges avec un client
public void run()
{
try
{
BufferedReader reader =
new BufferedReader(
new InputStreamReader( client.getInputStream() ) );
PrintWriter writer =
new PrintWriter(
new OutputStreamWriter( client.getOutputStream() ), true );
boolean fini = false;
while ( ! fini )
{
String ligne = null;
ligne = reader.readLine();
//System.out.println(ligne);
//System.out.println("RECEPTION CLIENT:"+ligne);
//création de joueur, le client doit envoyer NewJoueur: Vincent,Matte
//le numéro est attribuer par un variable incrémentable sur le serveur
if (ligne.startsWith("NewJoueur"))
{
String temp = Nettoyer(ligne);
String Nom = temp.substring(0,temp.indexOf(","));
String Pseudo = temp.substring(temp.indexOf(",")+1, temp.length());
if (Serveur.NombreJoueurs == 1)
{
Serveur.J1.SetNom(Nom);
Serveur.J1.SetPseudo(Pseudo);
writer.println("J1");
writer.flush();
} else if (Serveur.NombreJoueurs == 2)
{
Serveur.J2.SetNom(Nom);
Serveur.J2.SetPseudo(Pseudo);
writer.println("J2");
writer.flush();
} else if (Serveur.NombreJoueurs == 3)
{
Serveur.J3.SetNom(Nom);
Serveur.J3.SetPseudo(Pseudo);
writer.println("J3");
writer.flush();
} else if (Serveur.NombreJoueurs == 4)
{
Serveur.J4.SetNom(Nom);
Serveur.J4.SetPseudo(Pseudo);
writer.println("J4");
writer.flush();
}
if (Serveur.NombreJoueurs > 4)
{
writer.println("ERREUR: Trop de joueurs");
writer.flush();
} else Serveur.AjouterJoueur();
}
if (ligne.startsWith("Setup?"))
{
if (Serveur.NombreJoueurs <= 4)
{
writer.println("not ready");
writer.flush();
}
else
{
writer.println("Setup: " + Serveur.J1.GetPseudo() + "," + Serveur.J2.GetPseudo() + "," + Serveur.J3.GetPseudo() + "," + Serveur.J4.GetPseudo());
writer.flush();
}
}
if (ligne.contains("Attente"))
{
writer.println("J"+Serveur.TourJoueur + "Deplacement");
writer.flush();
Pr("J'envoie:"+ "J"+Serveur.TourJoueur + "Deplacement");
if (ligne.contains("AttenteQuestion")) //On recoit J2AttenteQuestion: V
{
if (ligne.contains("J"+Serveur.TourJoueur))
{
String Categorie;
String Question;
Categorie = ligne.substring(ligne.indexOf(":")+1, ligne.length());
Question = Serveur.BD.ObtenirQuestion(Categorie);//Envoie V pour vert, J pour Jaune .. etc..
//Exemple de reponse... J2: V03: Quel homme a marcher sur la terre? |A[Vincent matte] B[....
writer.println("DonneQuestions : " + Question );
writer.flush();
}
else
{
try
{
Thread.sleep(2000); // do nothing for 1000 miliseconds (1 second)
}
catch (InterruptedException e)
{
e.printStackTrace();
}
//Pr(ligne);
writer.println("not ready");
writer.flush();
}
}
}
if (ligne.startsWith("Reponse")) //Recoit ReponseJ1:V03A
{
String Reponse = ligne.substring(ligne.indexOf(":") +1, ligne.length()); // V03A
String Question = ligne.substring(ligne.indexOf(":"), (ligne.length()-1)); //V03
String CategorieString = ligne.substring(ligne.indexOf(":"), (ligne.indexOf(":")+1));
char Categorie = CategorieString.charAt(0);
boolean BonneReponse = false;
System.out.println("Contenu de la reponse (de la methode)" + Serveur.BD.VerifierReponse(Reponse));
if (Serveur.BD.VerifierReponse(Reponse).contains("Y"))
BonneReponse = true;
else
System.out.println("Le joueur a mal repondu");
//boolean BonneReponse = Serveur.BD.VerifierReponse(Reponse);
if (BonneReponse)
{
System.out.println("Le joueur a bien repondu");
//Serveur.BD.SetQuestionRepondue("Y", Question);
//Serveur.BD.AjouterScore(Categorie, Question);
//String Score = Serveur.BD.GetScore// (envoyer pseudo en string et retourne un score
// writer.println(Serveur.TourJoueur + ": " + "bravo" + "("+ Score +")");
//mettre tour joueur = J +1;
if (Serveur.TourJoueur.equals("4"))
{
Serveur.TourJoueur = "1";
}
else
{
int temp = Integer.parseInt(Serveur.TourJoueur);
temp++;
Serveur.TourJoueur = Integer.toString(temp);
System.out.println("Le joueur + " + Serveur.TourJoueur + " peut maintenant joué");
}
}
else
{
writer.println(Serveur.TourJoueur + ": " + "fail");
writer.flush();
if (Serveur.TourJoueur.equals("4"))
{
Serveur.TourJoueur = "1";
}
else
{
int temp = Integer.parseInt(Serveur.TourJoueur);
temp++;
Serveur.TourJoueur = Integer.toString(temp);
System.out.println("Le joueur + " + Serveur.TourJoueur + " peut maintenant joué");
}
}
}
}
reader.close();
writer.close();
client.close();
}
catch ( IOException ioe )
{
/*
* Ici on choisit de quitter l'application, mais il y aurait peut-être
* moyen de traiter l'exception.
*/
System.err.println( "Erreur d'entre-sortie" );
System.exit( 1 );
}
}
public void Pr(String pr)
{
System.out.println(pr);
}
public String Nettoyer(String Crap)
{
//Enleve n'importe quoi devant.. ex Lol: blabla, devient Blabla
int index = Crap.indexOf(":");
index++;
String Propre = Crap.substring(index, Crap.length());
return Propre;
}
}
I think you need a writer.flush()
after you send a message.
精彩评论