web-dev-qa-db-fra.com

comment faire en sorte que le socket client attende les données du socket du serveur

J'ai un programme client/serveur simple. Le serveur peut accepter la connexion de plusieurs clients. Actuellement, c'est ce qui se passe chez mon client.
1) Tapez LIST dans le client. Le serveur renverra tous les fichiers du répertoire courant au client. 2) Tapez "Hello" dans le client. Le serveur doit renvoyer "Bonjour". Cependant, dans le client, le client lit vide.
J'entre "QUIT" dans le client. Je ne vois que le message Hello renvoyé du serveur.
Je n'arrive pas à comprendre pourquoi le client ne lit pas le message Hello après son envoi par le serveur.

Code client

import Java.net.*;   // Contains Socket classes
import Java.io.*;    // Contains Input/Output classes
import Java.nio.CharBuffer;

class ClntpracticeSandbox{

   public static void main(String argv[]){


   try{
//     
       Socket client=new Socket("localhost", 7777);
       System.out.println("Connected to server " + client.getInetAddress() 
             + ": " + client.getPort());
       System.out.println("local port is " + client.getLocalPort());

       BufferedReader kbreader;
       BufferedWriter writer;
       BufferedReader reader;

       kbreader = new BufferedReader(new InputStreamReader(System.in));
       writer = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
       reader = new BufferedReader(new InputStreamReader(client.getInputStream()));

       String data = "", datakb, line=null;

       do{
            System.out.print("Text to the server? ");
            datakb = kbreader.readLine();
            writer.write(datakb);
            writer.newLine();
            writer.flush();

            System.out.print("Received from the Server:  ");
            line = reader.readLine();
            while (line.equals("")==false){
                System.out.println(line);
                line = reader.readLine();
            }
       } while (datakb.trim().equals("QUIT")==false);          
       client.close();
       System.exit(0);

      }catch(Exception e){
          System.err.println("Exception: " + e.toString());
      }
   }
}

Code serveur

import Java.net.*;   // Contains Socket classes
import Java.io.*;    // Contains Input/Output classes
import Java.nio.file.*;

class SrvrpracticeSandbox{
    public static void main(String argv[]) throws IOException {
        ServerSocket s = new ServerSocket(7777);

        System.out.println("Server waiting for client on port " + s.getLocalPort());
        int count = 0;
        do {
            count = count + 1;
            Socket connected = s.accept();
            new clientThread(connected, count).start();
        } while (true);

    }
}

class clientThread extends Thread {

    Socket myclientSocket = null;
    int mycount;
    DataInputStream is = null;
    PrintStream os = null;


    public clientThread(Socket clientSocket, int count) {
        this.myclientSocket = clientSocket;
        this.mycount = count;
    }

    public void run() {
        try {

            System.out.println("New connection accepted " + myclientSocket.getInetAddress() + ": " + myclientSocket.getPort());

            BufferedReader reader;
            BufferedWriter writer;

            reader = new BufferedReader(new InputStreamReader(myclientSocket.getInputStream()));
            writer = new BufferedWriter(new OutputStreamWriter(myclientSocket.getOutputStream()));

            String data; 
            String testdirectory = "file1.txt\nfile2.txt\nfile3.txt";
            do{
                data = reader.readLine();
                System.out.println("Received from " +mycount + ":" + data);
                if (data.equals("LIST")) {
                    writer.write(mycount + "\n"+"150 - Transfer Initiated."+"\n"+
                            "DATA " +returnDirectoryList().getBytes().length + "\n" + 
                            returnDirectoryList() + "\r\n"); 
                } else {
                    writer.write("Server Echos to " + mycount + ":"+ data + "\n"+"This is a new line."+"\r\n"); 
                }                
                writer.newLine();
                writer.flush();

            }while (data.equals("QUIT") == false); 

            myclientSocket.close();
            System.exit(0);
        } catch (IOException ex) {
        }
    }
    private String returnDirectoryList()
    {
        String files = "";
        Path dir = Paths.get(".");
        try {
            DirectoryStream<Path> stream =
            Files.newDirectoryStream(dir);
            for (Path file: stream) {
                files = files + file.getFileName() +"\n";
            }
        } catch (IOException | DirectoryIteratorException x) {
            System.err.println("returnDirectoryList "+x.toString());
        }
        return files;        
    }
}
12
shresthaal

Le problème vient du fait qu'il manque au client une ligne vide lors de la lecture de la sortie LIST du serveur. C'est pourquoi, après la commande LIST, le serveur et le client ne sont plus synchronisés.

Dans le code client, ajoutez ces deux lignes à la fin de la boucle do while. Do {

if (datakb.equals("LIST"))
        reader.readLine();
}while( ..)

Il aurait dû lire la ligne manquée et le problème devrait disparaître.

Désolé, je ne parle pas anglais, c'est ma première réponse. Essayez d'attendre la réponse du serveur:

   do{
        System.out.print("Text to the server? ");
        datakb = kbreader.readLine();
        writer.write(datakb);
        writer.newLine();
        writer.flush();

        System.out.print("Received from the Server:  ");

        DataInputStream dataInputStream = new DataInputStream(client.getInputStream());

        int attempts = 0;
        while(dataInputStream.available() == 0 && attempts < 1000)
        {
            attempts++;
            Thread.sleep(10)
        }

        reader = new BufferedReader(dataInputStream);
        line = reader.readLine();

        while (line.equals("")==false){
            System.out.println(line);
            line = reader.readLine();
        }
   } while (datakb.trim().equals("QUIT")==false);          
   client.close();
   System.exit(0);

  }catch(Exception e){
      System.err.println("Exception: " + e.toString());
  }
  ...
9
ToñitoG

Vous envoyez toutes les commandes au serveur et votre serveur ne recherche que "LIST" en tant que commande spéciale, tout le reste sera traité par la partie "echo".

if (data == null) {
  continue;
}
if (data.equals("LIST")) {
  writer.write(mycount + "\n" + "150 - Transfer Initiated." + "\n" +
    "DATA " + returnDirectoryList().getBytes().length + "\n" +
    returnDirectoryList() + "\r\n");
} else {
  writer.write("Server Echos to " + mycount + ":" + data + "\n" + "This is a new line." + "\r\n");
}

J'ai essayé avec votre code et les petites modifications ci-dessus (depuis que j'ai NPE) et la sortie ressemble à

DU CÔTÉ SERVEUR:

Server waiting for client on port 7777
New connection accepted /127.0.0.1: 52889
Received from 1:peter  
Received from 1:LIST

CÔTÉ CLIENT:

Connected to server localhost/127.0.0.1: 7777
local port is 52889
Text to the server? peter
Received from the Server:  Server Echos to 1:peter
This is a new line.
Text to the server? LIST
Received from the Server:  1
150 - Transfer Initiated.
DATA 6
Files
Text to the server? 

N'est-ce pas le comportement attendu?

1
Peter Liljenberg