没有关闭插座的管道破损

时间:2018-12-02 18:08:40

标签: java multithreading sockets datamodel

我制作了这个简单的客户端-服务器程序,用于管理电子邮件类型的对象。当我运行客户端时,该客户端应该收到电子邮件的ArrayList,它停止工作,并且在服务器上收到“管道中断”错误。这是服务器的代码:

    public void run() {
        String nomeAccount = "";
        try {
            //PHASE 1: The server receives the email
            try {
                BufferedReader in = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
                nomeAccount = in.readLine();
            } catch (IOException ex) {
                System.out.println("Not works");
            }

            //PHASE 2: I'm getting all the emails from the files
            File dir = new File("src/server/" + nomeAccount);
            String[] tmp = new String[5];
            ArrayList<Email> arr = new ArrayList<Email>();
            DateFormat format = new SimpleDateFormat("DD-MM-YYYY", Locale.ENGLISH);
            int i = 0;
            for (File file : dir.listFiles()) {
                if (file.isFile() && !(file.getName().equals(".DS_Store"))) {
                    try (BufferedReader br = new BufferedReader(new FileReader(file))) {
                        String line;
                        while ((line = br.readLine()) != null) {
                            tmp[i++] = line;
                        }
                    } catch (IOException ex) {
                        System.out.println("Cannot read from file");
                    }
                    Date data = format.parse(tmp[3]);
                    arr.add(new Email((Integer.parseInt(tmp[0])), tmp[1], nomeAccount, tmp[2], tmp[4], data));
                    i = 0;
                }
            }

            //PHASE 3: The server sends the ArrayList to the client
            try {
                ObjectOutputStream objectOutput = new ObjectOutputStream(incoming.getOutputStream());
                objectOutput.writeObject(arr);
            } catch (IOException e) {
                System.out.println("Failed to send ArrayList");
                e.printStackTrace();
            }
        } catch (ParseException ex) {
            Logger.getLogger(ServerController.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                incoming.close();
            } catch (IOException ex) {
                Logger.getLogger(ServerController.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

错误发生在行objectOutput.writeObject(arr); 这是客户端,它会列出我接下来要发布的错误列表:

public void loadData() throws IOException, ClassNotFoundException {
    Socket s = new Socket("127.0.0.1", 5000);
    ArrayList<Email> email = new ArrayList<Email>();

    /* PHASE 1: The client sends a string to the server */
    try {
        PrintWriter out = new PrintWriter(s.getOutputStream(), true);
        out.print(account + "\r\n"); // send the account name to server
        out.flush();

        /* PHASE 2: The client receives the ArrayList with the emails */
        ObjectInputStream inStream = new ObjectInputStream(s.getInputStream());
        email = (ArrayList<Email>) inStream.readObject();

        //Casting the arrayList
        emailList = FXCollections.observableArrayList(email);

        //Sorting the emails
        Collections.sort(emailList, (Email o1, Email o2) -> {
            if (o1.getData() == null || o2.getData() == null) {
                return 0;
            }
            return o1.getData().compareTo(o2.getData());
        });

    } finally {
        System.out.println("Closing the socket");
        s.close();
    }
}

错误列表:

    Exception in Application start method
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$154(LauncherImpl.java:182)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.StreamCorruptedException: unexpected block data
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1581)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2278)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2158)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2060)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1567)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:427)
    at java.util.ArrayList.readObject(ArrayList.java:797)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1158)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2169)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2060)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1567)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:427)
    at mailbox.DataModel.loadData(DataModel.java:66)
    at mailbox.ListController.initModel(ListController.java:28)
    at mailbox.MailBox.start(MailBox.java:37)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)

特别是,它停止在此行上工作:email = (ArrayList<Email>) inStream.readObject();。为什么即使在此过程中没有套接字被关闭的情况下,也会收到 java.io.StreamCorruptedException:意外的块数据? 编辑: 电子邮件类别:

    public class Email implements Serializable {

private final IntegerProperty id = new SimpleIntegerProperty();

public final IntegerProperty IDProperty() {
    return this.id;
}

public final Integer getID() {
    return this.IDProperty().get();
}

public final void setID(final Integer id) {
    this.IDProperty().set(id);
}

private final StringProperty mittente = new SimpleStringProperty();

public final StringProperty MittenteProperty() {
    return this.mittente;
}

public final String getMittente() {
    return this.MittenteProperty().get();
}

public final void setMittente(final String mittente) {
    this.MittenteProperty().set(mittente);
}

private final StringProperty destinatario = new SimpleStringProperty();

public final StringProperty DestinatarioProperty() {
    return this.destinatario;
}

public final String getDestinatario() {
    return this.DestinatarioProperty().get();
}

public final void setDestinatario(final String destinatario) {
    this.DestinatarioProperty().set(destinatario);
}

private final StringProperty oggetto = new SimpleStringProperty();

public final StringProperty OggettoProperty() {
    return this.oggetto;
}

public final String getOggetto() {
    return this.OggettoProperty().get();
}

public final void setOggetto(final String oggetto) {
    this.OggettoProperty().set(oggetto);
}

private final StringProperty testo = new SimpleStringProperty();

public final StringProperty TestoProperty() {
    return this.testo;
}

public final String getTesto() {
    return this.TestoProperty().get();
}

public final void setTesto(final String testo) {
    this.TestoProperty().set(testo);
}

private final ObjectProperty<Date> data = new SimpleObjectProperty<Date>();

public final ObjectProperty<Date> DataProperty() {
    return this.data;
}

public final Date getData() {
    return this.data.get();
}

public final void setData(final Date data) {
    this.data.set(data);
}

public Email(int id, String mittente, String destinatario, String oggetto, String testo, Date data) {
    setID(id);
    setMittente(mittente);
    setDestinatario(destinatario);
    setOggetto(oggetto);
    setTesto(testo);
    setData(data);
}

private void writeObject(java.io.ObjectOutputStream out) throws IOException {
    out.writeInt(getID());
    out.writeUTF(getMittente());
    out.writeUTF(getDestinatario());
    out.writeUTF(getOggetto());
    out.writeUTF(getTesto());
    out.writeObject(getData());
}

private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {

    try {

        Field field = this.getClass().getDeclaredField("id");
        field.setAccessible(true);
        field.set(this, new SimpleIntegerProperty());

        field = this.getClass().getDeclaredField("mittente");
        field.setAccessible(true);
        field.set(this, new SimpleStringProperty());

        field = this.getClass().getDeclaredField("destinatario");
        field.setAccessible(true);
        field.set(this, new SimpleStringProperty());

        field = this.getClass().getDeclaredField("oggetto");
        field.setAccessible(true);
        field.set(this, new SimpleStringProperty());

        field = this.getClass().getDeclaredField("testo");
        field.setAccessible(true);
        field.set(this, new SimpleStringProperty());

        field = this.getClass().getDeclaredField("data");
        field.setAccessible(true);
        field.set(this, new SimpleObjectProperty<Date>());

    } catch (NoSuchFieldException | IllegalAccessException e) {
        throw new IOException(e);
    }

    setID(in.readInt());
    setMittente(in.readUTF());
    setDestinatario(in.readUTF());
    setOggetto(in.readUTF());
    setTesto(in.readUTF());
    setData((Date) in.readObject());
}
}

0 个答案:

没有答案