2016-11-16 4 views
1

今私は奇妙なエラーに直面しました。私はSerializableオブジェクトで遊んでいた、私はソケット接続を介してお互いに通信する2つのオブジェクトを使用していた。 2つのアプリケーションは同じですが(ピア2ピア)、実行中で通信しようとするインスタンスが2つあります。Socket.getInputStreamの前にSocketInputStreamに何かを送信していますか?

ObjectInputStreamをソケットから手に入れようとしたような問題は、InputStreamです。私のエラーがreader = new ObjectInputSream(cliIn)で発生した、私はそれで自己奇妙ですしてSocketTimeoutException(、私はread()で私のストリームを飾るないときことを期待しているだろうがスローされました。以下は、私は物事を行うことを試み方法です。

Socket clientSocket; 
clientSocket = new Socket(InetAddress.getByName(aHostIP), aPort); 
clientSocket.setSoTimeout(3000); 

InputStream cliIn = clientSocket.getInputStream(); 
ObjectInputStream reader = null; 
reader = new ObjectInputStream(cliIn); // <--- Error here 
ObjectOutputStream writer; 
writer = new ObjectOutputStream(new BufferedOutputStream(
    clientSocket.getOutputStream() 
)); 

writer.writeObject(new Request(aPort)); 
writer.flush(); 

どのような奇妙なのは、私は(他のオブジェクトが要求に応えているだろう、その時点で)OutputStreamに書き込まれた後までObjectInputStreamの作成を移動した場合、その後、これ以上のエラーがなかったということである。

Socket clientSocket; 
clientSocket = new Socket(InetAddress.getByName(aHostIP), aPort); 
clientSocket.setSoTimeout(3000); 

ObjectOutputStream writer; 
writer = new ObjectOutputStream(new BufferedOutputStream(
    clientSocket.getOutputStream() 
)); 

writer.writeObject(new Request(aPort)); 
writer.flush(); 

InputStream cliIn = clientSocket.getInputStream(); 
ObjectInputStream reader = null; 
reader = new ObjectInputStream(cliIn); // <--- No more error 

他の(応答側)は次のようになります:

ObjectInputStream in = new ObjectInputStream(aConnection.getInputStream()); 
Object req = in.readObject(); 
SysIO.print("FROM OBJECT! : " + req.toString()); 
SysIO.print("FROM OBJECT! Port: " + ((Request) req).getPort()); 

Request res = new Request(15); 

ObjectOutputStream out = new ObjectOutputStream(
     new BufferedOutputStream(aConnection.getOutputStream())); 
out.writeObject(res); 
out.flush(); 

これで問題は解決しましたが、将来の参考のために問題が何かを知りたいと思います。私はそれが正確に言うことは困難かもしれないが、多分さらなる調査、同時性の問題のためのいくつかのポインタを持っていることがわかります、私はソケットやバッファを間違って使用していますか?

(。私はそれがやや明確にするために処理し、いくつかのエラーが取り残されている)

答えて

0

答えはObjectInputStream documentationである:

public ObjectInputStream(InputStream in) 
        throws IOException 

が指定されたInputStreamから読み込むObjectInputStreamを作成します。 シリアル化ストリームヘッダーがストリームから読み込まれ、検証されます。このコンストラクタは、対応するObjectOutputStreamがヘッダを書き込んでフラッシュするまでブロックします。

セキュリティマネージャがインストールされている場合、このコンストラクタは、ObjectInputStream.readFieldsまたはObjectInputStream.readUnsharedメソッドをオーバーライドするサブクラスのコンストラクタによって直接的または間接的に呼び出されたときに、 "enableSubclassImplementation" SerializablePermissionをチェックします。

パラメータ:

in - 入力ストリームが

から読み取るための例外:

StreamCorruptedException - ストリームヘッダが正しくない場合

IOException - I/Oエラーが、一方が発生した場合読み込みストリームヘッダ

SecurityException - in

建設中にnullの場合、ストリームは、ソケットからのシリアル化のヘッダーを読み取るしようとしているが、ソケットがタイムアウトを読んで - 信頼されていないサブクラスが違法なセキュリティに敏感な方法

NullPointerExceptionをオーバーライドする場合相手がまだシリアル化されたオブジェクトを送信していないためです。

+0

お返事ありがとうございました。だから、これは 'SocketTimeoutException'をスローする頭を得るために読んだのですか?私が理解する限り、バッファが空であるかどうかを100%確実にチェックする方法はありません。そのようなアクションが必要なのか、それとも上記のように入出力ストリームのオープンをサーバに合わせるだけで十分ですか? (ここで示唆されているように(?))(0120-325-566/2671179) –

+0

はい、ソケットのタイムアウトは、その時点で読み込み可能なヘッダがないため、ストリームヘッダの読み込みによるものです。サーバが 'ObjectOutputStream'ヘッダを送信するまで、クライアントは' ObjectInputStream'を作成することはできません。クライアントが最初に 'ObjectOutputStream'を送信するまでは発生しません。 –

関連する問題