Клиент TCP-сервера, клиент печатает только входящую строку, когда сокет сервера закрыт - PullRequest
0 голосов
/ 26 мая 2020

Для школьного проекта нам нужно подключить сервер к клиенту и получить статистику с сервера. Мы хотим распечатать статистику в командной строке клиента. Сервер выполняет команду, отправляет результат клиенту, а клиент выводит результат в свою консоль. Но проблема в том, что клиент начинает печатать результаты только после закрытия серверного сокета.

Мы запускаем код сервера на виртуальной машине Ubuntu и код клиента на моем ноутбуке windows. Когда мы запускаем оба класса локально, они делают то, что мы хотим. Но когда мы запускаем серверную часть на виртуальной машине, клиентская сторона ожидает закрытия сокета.

Код клиента:

import java.io.*;
import java.net.Socket;


public class Client {
    public static void main(String[] args) throws IOException, InterruptedException {

        try{
            Socket s = new Socket("localhost", 80);
            s.setTcpNoDelay(true);
            PrintWriter pr = new PrintWriter(s.getOutputStream());
            pr.println("hello");
            pr.flush();

            InputStreamReader in = new InputStreamReader(s.getInputStream());
            BufferedReader bf = new BufferedReader(in);

            String str = bf.readLine();
            System.out.println("server: " + str);

            //todo dit moet in server.java gebeuren. Geen reden om elke keer hetzelfde commando door te sturen: wel extra veiligheidsrisicos
            while (true){
                String resultaat = bf.readLine();
                System.out.println(resultaat);
                Thread.sleep(1000);
            }
        }
        catch(Exception e){
            System.out.println("can't connect");
        }
    }
}

Код сервера:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class Server {
    public static void main(String[] args) throws IOException, InterruptedException {

        ServerSocket ss = new ServerSocket(80);
        Socket s = ss.accept();
        s.setTcpNoDelay(true);

        System.out.println("client connected");
        try {
            InputStreamReader in = new InputStreamReader(s.getInputStream());
            BufferedReader bf = new BufferedReader(in);
            String welcome = bf.readLine();
            System.out.println("Client: " + welcome);

            PrintWriter pr = new PrintWriter(s.getOutputStream());
            //grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage "%"}' ; uptime -p ; df /dev/sda1
            String cmd = "ping www.google.com";

            pr.println("Welcome client");
            pr.flush();

            //todo commando's in deze class zetten en om de zoveel tijd de resultaten doorsturen. Dus niet meer reageren op commando's
            while (true) {
                ArrayList<String> resultaat = runCommand(cmd);
                for (String str : resultaat
                ) {
                    pr.println(str);
                    pr.flush();
                }
                Thread.sleep(1000);
            }
        }
        catch (InterruptedException e){
            s.close();
        }
    }

    private static ArrayList<String> runCommand(String str) {
        ArrayList<String> resultaten = new ArrayList<>();
        try {
            Process process = Runtime.getRuntime().exec(str);
            BufferedReader ret = new BufferedReader(new InputStreamReader(process.getInputStream()));                   //vertaald bytes naar karakters van het eerste bericht van de client
            String line;                                                                                                //output van bufferedreader

            while ((line = ret.readLine()) != null) {
                String resultaat = ret.readLine();
                System.out.println(resultaat);
                resultaten.add(resultaat);
                System.out.println(ret.readLine());
            }
            System.out.println(resultaten);
        } catch (IOException e) {
            e.printStackTrace();
            resultaten.add(e.getMessage());
        }
        return resultaten;
    }
}

1 Ответ

0 голосов
/ 26 мая 2020

вы помещаете свой результат на сервер в Arraylist, поэтому он никогда не отправляется клиенту, попробуйте это

public class Server {

   public static void main(String[] args) throws IOException, InterruptedException {

        ServerSocket ss = new ServerSocket(8000);
        Socket s = ss.accept();
        s.setTcpNoDelay(true);

        System.out.println("client connected");
        try {
            InputStreamReader in = new InputStreamReader(s.getInputStream());
            BufferedReader bf = new BufferedReader(in);
            String welcome = bf.readLine();
            System.out.println("Client: " + welcome);

            PrintWriter pr = new PrintWriter(s.getOutputStream());
            // grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage
            // "%"}' ; uptime -p ; df /dev/sda1
            String cmd = "ping www.google.com";

            pr.println("Welcome client");
            pr.flush();

            Process process = Runtime.getRuntime().exec(cmd);
            BufferedReader ret = new BufferedReader(new InputStreamReader(process.getInputStream()));
            while (ret.readLine() != null) {
                pr.println(ret.readLine());
                pr.flush();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            s.close();
            ss.close();
        }
    }
}
...