能够成功写入数据,但无法从服务器读取数据

时间:2018-09-30 03:02:39

标签: java json sockets

我有两个类的服务器和客户端。我在智能上同时运行服务器和客户端。我能够将数据写入服务器上的Json文件,但是当涉及到读取数据时,我无法读取它。当我尝试读取数据时,我的应用程序没有响应。我是套接字编程的新手,请帮助我。

这是客户端上的代码

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();  
    }
}

我还有另一个称为显示控制器的类,该类正在通过传递套接字对象来调用方法。这是该类的代码。

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 :(得分:0)

您的代码中有几个问题。

  1. 主要的一个在Server类的main方法中。您的服务器仅接受一个连接。该连接将写入并读取json文件,然后您的main方法结束。如果您的主程序结束,则服务器不可用。这意味着连接的第一个客户端可以工作并写入文件,但是任何后续连接都不会连接,因为不再有服务器接受连接。典型的服务器通过使用以true为条件的while循环来无限期地运行。

没有线程的服务器的示例结构:

    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();
        }
      }
    }
  1. 无论客户端需要什么,您的服务器始终会同时执行写入和读取json文件的操作。服务器应该以某种方式允许客户端传达其想要执行的操作,然后仅执行客户端要求的操作。如果使用上面的框架代码,则此逻辑将进入logicToServeAClient类的方法ClientInstanceOnTheServer中。服务器和客户端使用socket对象的输入和输出流相互通信。服务器和客户端需要事先就客户端需要哪些命令/操作以及服务器愿意提供的服务达成一致。在您的情况下,它将是READWRITE。然后,您将在客户端和服务器之间创建一个协议(协议),内容涉及如何将这些命令发送到服务器以及服务器将如何响应每个命令的客户端。

协议示例:

// 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.

所有这些都可以通过套接字的输入和输出流来实现

区分ClientClientInstanceOnTheServer类之间的区别很重要。客户端是您的Client类,它连接到服务器,而ClientInstanceOnTheServer保持连接,并运行服务器代码,该代码为Client类请求的命令提供服务。在以上协议中,无论何时提及客户端,都是指Client类。每当提及服务器时,都是指ClientInstanceOnTheServer类。

您可以在Google上找到更多示例,例如:http://cs.lmu.edu/~ray/notes/javanetexamples/。但是,这应该可以帮助您解决问题。

欢呼