2016-03-21 4 views
0

Я получаю EOFException из следующего кода:ObjectInputStream не в состоянии распознать мой объект Формат данных

if (!(in.read() == -1)) 
{ 
    CANDataInfo canData = (CANDataInfo) in.readObject(); 
    System.out.println(canData.toString()); 
    bw.write(canData.toString()); 
} 
else 
{ 
    System.out.println("in.read() == -1 "+in.readObject()); 
    jLab0x28.setText("No more bytes to read "); 
} 

Я делаю сокет программирования, где сервер отправляет Удерживание данных клиенту в некотором интервале. Данные, переданные от сервера к клиенту через сокет, имеют тип CANDataInfo, который я разработал. На стороне клиента, пока я печатаю данные, я получаю исключение. Поскольку чтение объекта всегда равно -1, я не могу регистрировать данные в каком-либо файле.

сервера Код Side:

private ServerSocket server = null; 
private Socket client = null; 
private ObjectOutputStream out; 
public static final String TAG = "APP1"; 

private void structureData(CANDataInfo canDataInfo) 
{ 
    try 
    { 
     if(server == null) 
     { 
      server = new ServerSocket(38301); 
      server.setSoTimeout(0); 
     } 
     client = server.accept(); 
     Log.e("Server ", ""+client.isConnected()); 
     Log.e("Data ", ""+canDataInfo.toString()); 

     if(!client.isConnected()) 
     { 
      Log.e("Server ", "client.isConnected() "+client.isConnected()); 
      server.close(); 
     } 

     out = new ObjectOutputStream(client.getOutputStream()); 
     out.writeObject(canDataInfo); 

     out.close(); 
    } 
    catch (Exception ex) 
    { 
     Log.e(CANManagerSetUp.TAG, "" + ex); 
    } 
} 

стороне клиента Код{Не чистый раствор, см ответа от EJP}

package com.cnh.socket.client; 

import java.io.BufferedWriter; 
import java.io.EOFException; 
import java.io.File; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.net.Socket; 

import javax.swing.JLabel; 

import cantest.setup.CANDataInfo; 


public class ThreadListener 
{ 
    Socket client = null; 
    ObjectInputStream in = null; 
    ListenFor0X28 runnableListenFor0X28 = null; 
    boolean continueMe; 


    public class ListenFor0X28 implements Runnable 
    { 
     JLabel jLab0x28; 

     public ListenFor0X28(){} 

     public ListenFor0X28(boolean stop, JLabel jLab0x28) 
     { 
      continueMe = stop; 
      this.jLab0x28 = jLab0x28; 
     } 

     public void run() 
     { 

      while(continueMe) 
      { 
       try 
       { 
        client = new Socket("localhost", 38301); 
        in = new ObjectInputStream(client.getInputStream()); 
        if(client.isConnected()) 
        { 
         jLab0x28.setText("Connected to Server"); 
         appendFile(continueMe, jLab0x28, client); 

        } 
        else 
        { 
         System.out.println("Client is trying to connect"); 
         jLab0x28.setText("Client is trying to connect"); 
        } 
       } 
       catch(Exception ex) 
       { 
        ex.printStackTrace(); 
        System.err.println("Before Append "+ex.toString()); 
       } 
      } 
     } 
    } 
    BufferedWriter file = getFile("C:\\ISSUE124_Resolved.txt"); 
    private void appendFile(boolean continueMe, JLabel jLab0x28, Socket client) 
    { 
     try 
     { 
      if(!client.isClosed()) 
      { 
       try 
       { 
        CANDataInfo canData = (CANDataInfo) in.readObject(); 
        System.out.println(canData.toString()); 
        file.write(canData.toString()); 
        file.flush(); 

       } 
       catch (EOFException exp) 
       { 
        continueMe = true; 
        System.out.println("A Stream has finished "+exp.toString()+"\n"); 
       } 
       catch (ClassNotFoundException exp) 
       { 
        exp.printStackTrace(); 
        System.err.println(exp.toString()); 
        continueMe = false; 
       } 
      } 

      if(!continueMe) 
      { 
       file.close(); 
       client.close(); 
       in.close(); 
       jLab0x28.setText("Socket is closed "+client.isClosed()); 
      } 

     } 
     catch(IOException exp) 
     { 
      exp.printStackTrace(); 
      System.err.println("Exception "+exp.toString()); 
      jLab0x28.setText(exp.getMessage()); 
      continueMe = false; 
     } 
    } 

    public BufferedWriter getFile(String path) 
    { 
     try 
     { 
      File file = new File(path); 
      if (!file.exists()) 
      { 
       file.createNewFile(); 
      } 
      FileWriter fw = new FileWriter(file.getAbsoluteFile()); 
      return new BufferedWriter(fw); 
     } 
     catch (IOException e) 
     { 
      e.printStackTrace(); 
     } 
     return null; 
    } 
} 

Исключение Stack: {Перед разрешающую}

java.io.EOFException 
    at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source) 
    at java.io.ObjectInputStream.readObject0(Unknown Source) 
    at java.io.ObjectInputStream.readObject(Unknown Source) 
    at com.cnh.socket.client.ThreadListener.appendFile(ThreadListener.java:73) 
    at com.cnh.socket.client.ThreadListener.access$0(ThreadListener.java:65) 
    at com.cnh.socket.client.ThreadListener$ListenFor0X28.run(ThreadListener.java:48) 
    at java.lang.Thread.run(Unknown Source) 
Data received in unknown format java.io.EOFException 
+0

Распечатайте stacktrace с помощью 'classNot.printStackTrace()' - или по крайней мере 'classNot.toString()'. Ваше текущее сообщение является неполным, так как оно не показывает, какое исключение было выбрано. –

+0

My Bad, у меня есть обновленный вопрос. Пожалуйста, проверьте.Спасибо, что указали на это –

+0

Почему вы вызывали неизвестное исключение? ClassNot' - еще одна загадка, поэтому вы должны называть 'getLocalizedMessage()' только для того, чтобы отбросить результат. – EJP

ответ

1

Вы должны удалить бессмысленный и ошибочный вызов read(), который выводит ваши потоки объектов не синхронизированными.

Пока вы на нем, вы также можете удалить все избыточные вызовы на isConnected(). Они ничего не делают. У вас, кажется, есть мания для вызова дополнительных методов, которые в основном ничего не делают или которые пытаются предсказать будущее. Попытайтесь сузиться.

EDIT В соответствии с просьбой я критикую не только ваш клиент, но и ваш код сервера.

Сервер:

private void structureData(CANDataInfo canDataInfo) 
{ 
    try 
    { 
     if(server == null) 

ServerSocket должны были созданы и настроены в конструкторе.

 { 
      server = new ServerSocket(38301); 
      server.setSoTimeout(0); 

Нулевое значение по умолчанию. Не указывайте значения по умолчанию. Удалить.

 } 
     client = server.accept(); 
     Log.e("Server ", ""+client.isConnected()); 

Ведение журнала isConnected() является избыточным. Удалить. Это всегда будет печатать true. Сокет - подключен. Вы просто приняли это. Если вы хотите зарегистрировать что-то полезное, зарегистрируйте удаленный адрес клиентского сокета.

 Log.e("Data ", ""+canDataInfo.toString()); 

Как могут быть какие-либо данные, если вы еще не читали? Если это инвариантные данные на стороне сервера, зачем регистрировать их при каждом приеме?

 if(!client.isConnected()) 
     { 
      Log.e("Server ", "client.isConnected() "+client.isConnected()); 
      server.close(); 
     } 

Этот тест никогда не может пройти, и блок кода не может быть введен, и если каким-то чудом он был введен, закрывает сокет сервера нелепый ответ. Удалите все это.

 out = new ObjectOutputStream(client.getOutputStream()); 
     out.writeObject(canDataInfo); 

     out.close(); 
    } 
    catch (Exception ex) 

Не поймать Exception. Поймать IOException.

{ 
     Log.e(CANManagerSetUp.TAG, "" + ex); 

Необходимо зарегистрировать класс исключения, его сообщение и трассировку стека. ""+ex этого не делает.

} 
} 

Клиент:

public class ThreadListener 
{ 
    Socket client = null; 
    ObjectInputStream in = null; 
    ListenFor0X28 runnableListenFor0X28 = null; 
    boolean continueMe; 


    public class ListenFor0X28 implements Runnable 
    { 
     JLabel jLab0x28; 

     public ListenFor0X28(){} 

     public ListenFor0X28(boolean stop, JLabel jLab0x28) 
     { 
      continueMe = stop; 
      this.jLab0x28 = jLab0x28; 
     } 

     public void run() 
     { 

      while(continueMe) 
      { 
       try 
       { 
        client = new Socket("localhost", 38301); 
        in = new ObjectInputStream(client.getInputStream()); 
        if(client.isConnected()) 

Клиент является подключен. Вы просто подключили его, когда вы построили Socket. И если каким-то чудом это не было связано, то вызов getInputStream() уже провалился бы с SocketException. Удалите этот тест. В общем, слишком много испытаний вещей, которые не могут быть истинными или не могут быть ложными в коде.

    { 
         jLab0x28.setText("Connected to Server"); 
         appendFile(continueMe, jLab0x28, client); 
        } 
        else 
        { 
         System.out.println("Client is trying to connect"); 
         jLab0x28.setText("Client is trying to connect"); 
        } 
       } 

else блок недоступен, и сообщение журнала 'Client is trying to connect' неверен. Удалите весь блок и else.

   catch(Exception ex) 

См. Выше. Не поймайте Exception. Захватите исключения, которые компилятор говорит вам об улове: в этом случае IOException и связанные с DNS.

   { 
        ex.printStackTrace(); 
        System.err.println("Before Append "+ex.toString()); 

См. Выше, как регистрировать исключения.

   } 
      } 
     } 
    } 
    BufferedWriter file = getFile("C:\\ISSUE124_Resolved.txt"); 

    private void appendFile(boolean continueMe, JLabel jLab0x28, Socket client) 
    { 
     try 
     { 
      if(!client.isClosed()) 
      { 
       try 
       { 
        CANDataInfo canData = (CANDataInfo) in.readObject(); 
        System.out.println(canData.toString()); 
        file.write(canData.toString()); 
        file.flush(); 
       } 
       catch (EOFException exp) 
       { 
        continueMe = true; 
        System.out.println("A Stream has finished "+exp.toString()+"\n"); 
       } 
       catch (ClassNotFoundException exp) 
       { 
        exp.printStackTrace(); 
        System.err.println(exp.toString()); 
        continueMe = false; 
       } 
      } 

      if(!continueMe) 
      { 
       file.close(); 
       client.close(); 
       in.close(); 

Вам не нужно закрывать входной поток и розетку. Так и будет. Общая практика заключается в том, чтобы закрыть внешний поток записи/вывода, если он есть, иначе входной поток.

   jLab0x28.setText("Socket is closed "+client.isClosed()); 
      } 

     } 
     catch(IOException exp) 
     { 
      exp.printStackTrace(); 
      System.err.println("Exception "+exp.toString()); 
      jLab0x28.setText(exp.getMessage()); 
      continueMe = false; 
     } 
    } 

    public BufferedWriter getFile(String path) 
    { 
     try 
     { 
      File file = new File(path); 
      if (!file.exists()) 
      { 
       file.createNewFile(); 
      } 

Здесь вы найдете (1) тестирование существующего файла и (2) создание нового файла.

  FileWriter fw = new FileWriter(file.getAbsoluteFile()); 

Здесь операционная система создаст новый файл независимо от того, что вы сделали выше. Таким образом, часть exists()/createNewFile() - это полная трата времени: два системных вызова, которые ничего не выполняют. Удалить их.

  return new BufferedWriter(fw); 
     } 
     catch (IOException e) 
     { 
      e.printStackTrace(); 
     } 
     return null; 

Плохая практика. Вы должны позволить этому методу выкинуть IOException и не поймать его внутренне, или вернуть null. В настоящее время, если этот метод выходит из строя, вы получите instrutable NullPointerException, когда вы идете использовать его возвращаемое значение.

} 
} 
+0

спасибо за информацию, я сделал изменения, сотрудничающие с вашими комментариями и этим потенциальным ответом. Я заканчиваю EOF Exception. Я знаю EOFException, когда поток ввода достиг цели, но если я делаю if (! (In.read() == -1)), я ничего не получаю, и даже мой сервер на Android Display не отправляет никаких данных и просто продолжает укладывать Это. –

+0

, когда вы будете ссылаться на этот вопрос http://stackoverflow.com/questions/35935354/sending-continuos-data-from-service-to-activity-at-really-very-high-speed, вы поймете, что я на самом деле пытаясь выполнить. и почему я должен был сделать все в цикле while. В любом случае, пожалуйста, проверьте мой код на стороне клиента и, если возможно, предоставьте мне обратную связь на чистый путь. я согласен с ответом –

+0

@PawankumarDubey Вы, кажется, уже достаточно узнали из моего ответа, чтобы включить все это в свой код, без необходимости повторять его для вас, и мой ответ уже содержит объяснение. По просьбе я критиковал ваш код. Мне не нужно было бы читать другой вопрос, чтобы понять, что вы пытаетесь выполнить здесь. Я ничего не говорил о циклах while, и я не понимаю, почему вы упомянули об этом. – EJP

2

В клиенте

if (!(in.read() == -1)) 
{ 
    CANDataInfo canData = (CANDataInfo) in.readObject(); 
    System.out.println(canData.toString()); 
    bw.write(canData.toString()); 
} 

Первая строка считывает один байт из входного потока. Это фактически первый байт объекта, который был написан сервером. Таким образом, поток больше не выравнивается правильно, поэтому следующие readObject() терпят неудачу.

+0

Я только что попробовал передать строковый объект с сервера, например out.writeObject (canDataInfo.toString); и на клиентских данных печатается в другом состоянии, то есть когда (in.read() == -1). Как я могу связать это с вашим ответом, пожалуйста, найдите обновленный вопрос для точного исключения –

+0

@PawankumarDubey Я не знаю, почему вы передаете результат 'toString()' методу, чем можете принять любой объект Serializable, но если вы не отправили байт впереди этого кода, который вы отправили, не удастся. – EJP

+0

@JimGarrison Можете ли вы пройти через весь исходный код клиентской стороны? –

Смежные вопросы