Может успешно записывать данные, но не может прочитать данные с сервера - PullRequest
0 голосов
/ 30 сентября 2018

У меня есть два класса сервер и клиент.Я использую сервер и клиент на intelliji.Я могу записать данные в файл Json на сервере, но когда дело доходит до чтения данных, я не могу их прочитать.Мое приложение не отвечает, когда я пытаюсь прочитать данные.Я новичок в Socket Programming, пожалуйста, помогите мне.

Вот код на стороне клиента

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

public class Client {
    public String readDataFromServer(Socket socket) throws IOException {

        InputStreamReader inputStreamReader = new 
        InputStreamReader(socket.getInputStream());
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

        return bufferedReader.readLine();
    }

    public  void writeDataToServer(String obj) throws IOException {
        Socket socket = new Socket("localhost", 1299);
        OutputStreamWriter outputStreamWriter = new 
        OutputStreamWriter(socket.getOutputStream());
        PrintWriter printWriter = new PrintWriter(outputStreamWriter);
        printWriter.write(obj);
        printWriter.flush();
        printWriter.close();
    }
}

Вот код на стороне сервера

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

public class Server {
    static void writeJson (String str) throws IOException {
        FileWriter pw = null;
        try {
            pw = new FileWriter("MYJSON.json", true);
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }
        pw.write(str + '\n');
        pw.flush();
        try {

        } catch (Exception E) {
            E.printStackTrace();
        }
        pw.close();
    }

    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(1299);
        Socket socket = serverSocket.accept();

        InputStreamReader inputStreamReader = new     InputStreamReader(socket.getInputStream());
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String str = bufferedReader.readLine();
        writeJson(str);

        FileReader fileReader = new FileReader("MYJSON.json");
        BufferedReader buff = new BufferedReader(fileReader);
        OutputStreamWriter outputStreamWriter = new 
        OutputStreamWriter(socket.getOutputStream());
        PrintWriter printWriter = new PrintWriter(outputStreamWriter);

        printWriter.write(buff.readLine());
        printWriter.flush();  
    }
}

У меня есть другой класс с именем display controller, который вызывает метод, который вызывает метод, передавая объект сокета.Вот фрагмент кода из этого класса.

Client client = new Client();
button1.setOnAction(e-> {
            try {
                String str;

              while ((str = client.readDataFromServer(socket)) != null) {

                Object obj = null;
                try {
                  obj = jsonParser.parse(str);

Что я здесь не так делаю?Как мне это исправить?Спасибо

1 Ответ

0 голосов
/ 30 сентября 2018

В вашем коде есть пара проблем.

  1. Основная проблема заключается в методе main класса Server.Ваш сервер принимает только одно соединение.Это соединение записывает и читает файл json, а затем ваш основной метод завершается.Если ваша основная программа заканчивается, то сервер исчез.Это означает, что первый клиент, который подключится, будет работать и записывать в файл, но любые последующие подключения не будут подключаться, потому что сервер больше не принимает подключения.Типичные серверы работают бесконечно, используя цикл while с true в качестве условия.

Пример Структура сервера без потоков:

    public class Server {

      // this class represents an instance of a client connection to this server
      // It's an object that keeps track of the socket created by referencing
      // the connection.
      private class ClientInstanceOnTheServer {

        private Socket connectionToClient;

        public ClientInstanceOnTheServer(Socket connectionToClient) {
          this.connectionToClient = connectionToClient;
        }

        private void logicToServeAClient() {
          // here goes the logic that serves a client
        }

        public void run () {

          try {
            logicToServeAClient();
          } finally {
            try {
              socket.close();
            } catch (IOException e) {// handle exceptions!}
          }

        }

      }

      public static void main(String [] args) {
        try {
          ServerSocket serverSocket = new ServerSocket(1299);
          while (true) { // run indefinitely
             Socket socket = serverSocket.accept(); // accept connections from clients
             // keep track of the socket object as it represents a connection to a client
             // the server is responsible for keeping track of its connections to clients
             // Example:
             ClientInstanceOnTheServer client = new ClientInstanceOnTheServer(socket);
             client.run();
          }
        } finally {
          serverSocket.close();
        }
      }
    }

Пример Структура сервера с потоками: ПРИМЕЧАНИЕ. Приведенный ниже код представляет собой не полное решение с потоками, а пример, объясняющий, как работает сервер.

    public class Server {

      // this class represents an instance of a client connection to this server
      // It's an object that keeps track of the socket created by
      // the connection and it runs in a separate thread to not block
      // the main method thread on this server.
      private class ClientInstanceOnTheServer extends Thread {

        private Socket connectionToClient;

        public ClientInstanceOnTheServer(Socket connectionToClient) {
          this.connectionToClient = connectionToClient;
        }

        private void logicToServeAClient() {
          // here goes the logic that serves a client
        }

        public void run () {

          try {
            logicToServeAClient();
          } finally {
            try {
              socket.close();
            } catch (IOException e) {// handle exceptions!}
          }

        }

      }

      public static void main(String [] args) {
        try {
          ServerSocket serverSocket = new ServerSocket(1299);
          while (true) { // run indefinitely
             Socket socket = serverSocket.accept(); // accept connections from clients
             // keep track of the socket object as it represents a connection to a client
             // the server is responsible for keeping track of its connections to clients
             // and it should use a separate thread for each client to not block the main method thread.
             // Example:
             ClientInstanceOnTheServer client = new ClientInstanceOnTheServer(socket);
             client.start(); // this will execute the run method in ClientInstanceOnTheServer class.
          }
        } finally {
          serverSocket.close();
        }
      }
    }
Ваш сервер всегда делает и пишет, и читает файл json, независимо от того, что хочет клиент.Сервер должен как-то позволить клиенту сообщать, что он хочет сделать, и тогда он выполняет только то, что просил клиент.Если мы будем использовать приведенный выше скелетный код, эта логика будет реализована в методе logicToServeAClient класса ClientInstanceOnTheServer.Сервер и клиент используют входные и выходные потоки объекта socket для связи друг с другом.Сервер и клиент должны заранее договориться о том, какие команды / операции нужны клиенту и сервер готов обслуживать.В вашем случае это будет READ и WRITE.Затем вы создаете контракт (протокол) между клиентом и сервером о том, как отправлять эти команды на сервер и как сервер будет отвечать клиенту для каждой команды.

Пример протокола:

// client sends READ to server
// client waits for respond from server
// server read json file and send it to the client

// client sends WRITE to server
// server then waits for the client to send the string to write. 
// Once it receives the string, it writes it to the json file.

Все это достижимо при использовании потоков ввода и вывода сокета

Важно различать различия между классами Client и ClientInstanceOnTheServer.Клиент - это ваш класс Client, который подключается к серверу, а ClientInstanceOnTheServer хранит соединение, а также выполняет код сервера, который обслуживает команды, запрошенные классом Client.В приведенном выше протоколе всякий раз, когда упоминается клиент, имеется в виду класс Client.Всякий раз, когда упоминается, что сервер ссылается на класс ClientInstanceOnTheServer.

В Google можно найти больше примеров, например: http://cs.lmu.edu/~ray/notes/javanetexamples/. Однако это должно помочь вам решить проблему.

Ура

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...