2016-03-21 4 views
0

を認識することができません。ビアソケットでサーバからクライアントに渡されるデータは、私が開発したCANDataInfoオブジェクトです。クライアント側では、データを印刷しているうちに例外が発生しています。オブジェクトの読み取りは常に-1なので、私はいくつかのファイルにデータを記録することができません。ObjectInputStreamのは、私は次のコードから<code>EOFException</code>を取得しています、私のオブジェクトデータ形式

サーバーサイドコード:

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

例外スタック:{解決する前に}

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

私のバッド、私は更新された質問があります。チェックしてください。それを指摘してくれてありがとう –

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

このテストは合格したことがないことができ、コードブロックを入力することはできませんし、いくつかの奇跡によってそれが入力された場合は、サーバソケットをクローズすることはばかげ応答です。これをすべて削除します。

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()の部分は完全に時間の無駄です.2つのシステムコールは、まったく何も達成しません。削除してください。

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

悪い習慣。このメソッドはIOExceptionをスローし、内部的にキャッチしないようにするか、nullを返します。現在のところ、このメソッドが失敗した場合、その戻り値を使用するときには、NullPointerExceptionという不具合が発生します。

+0

情報をありがとう、私はあなたのコメントとこの潜在的な答えを協力して変更を行っている。私はEOF例外で終わっています。私は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私が実際に何を理解するか実行しようとしている。なぜ私はしばらくループを掛けなければならなかったのですか?とにかく、私のクライアント側のコードをチェックし、可能であれば、私にクリーンな方法でフィードバックを提供してください。私はあなたの答えを受け入れるでしょう –

+0

@ PawankumarDubeyあなたはすでに私の答えからあなたのコードにすべてを組み込むために十分なことを学んだようですが、私はあなたのためにそれを繰り返す必要はなく、私の答えはすでに説明を含んでいます。要求通りに私はあなたのコードを批評しました。あなたがここで何をしようとしているのかを理解するために別の質問を読む必要はありません。私はwhileループについて何も言わなかったので、なぜあなたがそれに言及するのか分かりません。 – EJP

2
クライアントで

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

最初の行には、入力ストリームから1つのバイトを読み取ります。これは、実際にはサーバーによって書き込まれたオブジェクトの最初のバイトです。したがって、ストリームはもはや正しく整列しないので、次のようになります。readObject()が失敗します。

+0

私はサーバーからout.writeObject(canDataInfo.toString)のような文字列オブジェクトを送信しようとしました。それ以外の場合、つまりwhen(in.read()== -1)でクライアントデータが印刷されています。どのように私はこれをあなたの答えに関連付けることができますか?正確な例外の更新された質問を見つけてください –

+0

@PawankumarDubey 'toString()'の結果をメソッドに渡す理由はわかりません。それより前の1バイトはあなたが投稿したコードは失敗します。 – EJP

+0

@JimGarrisonクライアント側のソースコード全体を一度ご覧いただけますか? –

関連する問題