Java: чтение из ObjectInputStream

Я только начал изучать Java. Моя задача — создать файловый сервер, который принимает определенные команды, такие как File Get, File Put и File Delete от нескольких клиентов с использованием Threading. Я использую пользовательский класс DataObject для сериализации и отправки команд и любых данных, которые могут сопровождать его. Клиент должен быть интерактивным в том смысле, что он предполагает ручной ввод пользователем различных команд. Это означает, что функция ObjectInputStream readObject() не будет работать в цикле while(true) из-за исключения EOFException. Что я могу сделать, чтобы серверный поток приостанавливался в readObject() до тех пор, пока не увидит следующий объект, а затем возобновлял цикл while(true)?

Код на сервере (запускается для каждого потока отдельно):

public void run() {
    ObjectInputStream is = null;
    ObjectOutputStream os = null;
    try{
        is = new ObjectInputStream(clientSocket.getInputStream());
        os = new ObjectOutputStream(clientSocket.getOutputStream());
        while (true) {
            input = (DataObject) is.readObject();
            //System.out.println("Input has been read");
            output = CommandProcessor.process(input);
            if(output.data == null) {
                os.writeObject(output);
                if(output.message.compareToIgnoreCase("Rsp Bye")==0){
                    clientSocket.close();
                }
            }
        }
    }

Код на клиенте:

    public Talker() {
            DataObject input = new DataObject(0), output = new DataObject(0);
            try {
                log = new PrintStream("/home/meher/log.txt");
                InetAddress serverAddress = InetAddress.getByName("127.0.0.1");
                Socket serverSocket = new Socket(serverAddress, port);
                os = new ObjectOutputStream(serverSocket.getOutputStream());
                is = new ObjectInputStream(serverSocket.getInputStream());
                CommandExecuter.Hello(output);
                write(output);
                read(input);
                while(not-end-of-user-input){ //Yet to code this part
                            //Execute commands
                    }
            }

person Anand    schedule 26.09.2010    source источник
comment
Надо сказать, что это довольно сложная задача для человека, который «только начал изучать Java».   -  person Roman    schedule 26.09.2010
comment
Завтра нужно выполнить задание по курсу «Распределенные операционные системы». Ожидаемый язык - Java.   -  person Anand    schedule 26.09.2010
comment
Пожалуйста, обратите внимание, что я не удосужился добавить сюда часть обработчиков исключений, но они есть в коде.   -  person Anand    schedule 26.09.2010


Ответы (2)


EOFException выбрасывается из readObject, когда поток заканчивается. В вашем случае, когда клиент закрывает свое соединение. Таким образом, если клиент отправляет объект на сервер и сразу же завершает работу, сервер прочитает один объект и получит EOFExcpetion в следующий раз, когда он попытается прочитать объект при уже закрытом соединении.

Возможно добавить QUIT-команду, в которой они оба соглашаются разорвать соединение?

person Alexander Sagen    schedule 26.09.2010
comment
Мой клиент не должен выходить, если нет определенного сообщения Bye. Клиент продолжает отправлять запросы, когда пользователь вводит команду типа File Get ‹filename› и нажимает клавишу ввода. Я хочу, чтобы соединение сохранялось все время. - person Anand; 26.09.2010
comment
Не видите, что заставляет клиента оставаться рядом? Если он пропустит еще не закодированную часть, он просто выйдет и прервет соединение. - person Alexander Sagen; 26.09.2010
comment
Большое спасибо. Я не понимал, что EOF придет из-за закрытого соединения. Я думал, что это произошло, потому что он не мог больше читать объекты, пока клиент не написал их снова. Цикл while (настоящий) на стороне клиента работал. :) - person Anand; 26.09.2010
comment
Использование команды QUIT не добавляет ничего полезного. TCP уже отправляет это через бит FIN. Явный QUIT только добавляет сложности, не добавляя никакой ценности. Вам нужно только явно поймать EOFException, что вы бы сделали в любом случае, если одноранговый узел по какой-то причине не может отправить QUIT. - person user207421; 27.03.2020

решение добавить сканер для ввода некоторых данных... на стороне записывающего объекта... это сохранит поток живым и доступным, он будет ждать ввода.....

Код сервера

  package com.cdac.Network;

  import java.io.IOException;
  import java.io.ObjectOutputStream;
  import java.net.ServerSocket;
  import java.net.Socket;
  import java.net.SocketException;
  import java.util.Scanner;

  import com.cdac.collection.Customer;

  public class Server {


  public static void main(String[] args) throws IOException,SocketException{
    ServerSocket ss=new ServerSocket(1888);
    Customer customer=new Customer(101);
    Socket s=ss.accept();
    System.out.println("connection establishd");

    Scanner scanner=new Scanner(System.in);
    ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());
    {
    oos.writeObject(customer);
scanner.next(); 
    }

}

 }

код клиента

    package com.cdac.Network;

  import java.io.IOException;
  import java.io.ObjectInputStream;
   import java.net.Socket;
   import java.net.SocketException;
   import java.net.UnknownHostException;

   import com.cdac.collection.Customer;

     public class Client {

    public static void main(String[] args) throws UnknownHostException,
        IOException, SocketException, ClassNotFoundException {

    Customer customer = new Customer(101, "amit", 500);

    // String str1,str2;
    Socket s = new Socket("localhost", 1888);

    ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
    {
        Object obj = ois.readObject();

        Customer c = (Customer) obj;
        System.out.println(c);
    }
}

}
person jayant    schedule 19.06.2013
comment
Сканер здесь ничего не дает. EOFException все равно будет выброшено. Правильно. - person user207421; 27.03.2020