- 締切済み
closeされたsocketへの動作について
現在、javaを使用してプログラムを作成しているのですが、closeされたsocketに対しての動作について質問があります。 クライアント側のプログラムに ObjectOutputStream.writeObject(send); ObjectOutputStream.flush(); ObjectInputStream.readObject(); というものがあったとします。 サーバ側でsocketをcloseし、上記のプログラムを走らせた場合writeObjectにてsocketExceptionを検出する場合とreadObjectでEOFExceptionを検出する場合の2パターンが起こりうるのですが、これはなぜでしょうか? なお、上記のwriteObjectの引数のsendはSerializeを継承して作成した自作クラスのオブジェクトです。
- みんなの回答 (1)
- 専門家の回答
みんなの回答
- anmochi
- ベストアンサー率65% (1332/2045)
関連するQ&A
- javaのObjectOutputStreamのエラーが消えません
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("test.txt")); oos.writeObject(text); ObjectInputStream ois = new ObjectInputStream(new FileInputStream("text.txt")); text = (LinkedList<String>)ois.readObject(); 最後の分のois.readObject()のなぜかClassNotFoundExceptionになってしまって先に進めないです。 これではあまり意味がないんですが、わかる方がいらっしゃいましたら教えてください
- 締切済み
- Java
- SocketのSend関数でのCLOSEの検知 [Linux]
Linux環境でSocket(dm:PF_INET,type:SOCK_STREAM)を使用しての、 Client&ServerプログラムをCで作成しているのですが、 そこでのSend関数の使い方についてご助力ください。 Client&Serverプログラムは下記のような動きをします。 [Client] ServerへConnectした後、複数のDataを数秒間隔でServerへ 送信(send関数使用)します。受信(recvやread関数等)は、 一切行いません。 [Server] ClientからのConnectを受け付けた後、Clientから受信(recv関数 使用)したDataを標準出力へ表示する。送信(sendやwrite関数 等)は、一切行いません。 さて、ここでもしClientプログラムがCloseを発行したり、マシン DOWN等の理由でConnectionが切断され、Server側のSocketが CLOSE_WAIT状態になった場合、Bufferに溜まっていたDataを すべて受けきった後、recv関数が0を返してくれるので 相手が終了したことがわかります。 ここからが質問のMainです。 では、もしServerプログラムがCloseを発行したり、マシン DOWN等の理由でConnectionが切断され、Client側のSocketが CLOSE_WAIT状態になっても、CLOSE_WAIT直後のsend関数が なぜか正常に処理されてしまいます。無論このDataは、 Server側は受け取りません。この次のsend関数実行時に EPIPEが返ってくるので、ここでようやくSocketが切断された ことが判ります。 これを何とかCLOSE_WAIT状態になった直後から、send関数で 切断を検知できるようにできないでしょうか。 よろしくお願いします。 以上
- ベストアンサー
- C・C++・C#
- "try{}catch(){}"文で"close()"はどのように書けばよいのでしょうか。
こんにちは、片岡と言います。 プログラム1は、Java言語で学ぶデザインパターン入門(結城浩さん著)の 433ページを参考にして書きました。 私は、プログラム1のclose()の書き方よりもプログラム2のようなclose()の書き方が、 良いと思っています。 なぜならば、プログラム1では、out.writeObject(memento)行の例外によって、 close()が実行されないからです。 私のこの考え方は正しいのでしょうか。 もっと良いclose()の書き方はあるのでしょうか。 ご存知の方はいらっしゃいませんか。 ●プログラム1 public class Main { public static void saveMemento(Memento memento) { try { ObjectOutput out = new ObjectOutputStream(new FileOutputStream("game.dat")); out.writeObject(memento); out.close(); } catch (IOException e) { e.printStackTrace(); } } … //以下略 } public class Memento implements Serializable { … //以下略 } ●プログラム2 public class Main { public static void saveMemento(Memento memento) { try { ObjectOutput out = new ObjectOutputStream(new FileOutputStream("game.dat")); out.writeObject(memento); } catch (IOException e) { e.printStackTrace(); } finally { if (out != null) { try { out.close(); } catch (IOException ex) { ex.printStackTrace(); } } } } … //以下略 } public class Memento implements Serializable { … //以下略 } なお、私の環境は以下の通りです。 OS: Microsoft Windows XP Professional SP2 開発環境:Eclipse 3.2.2 java: java version "1.4.2_13"
- ベストアンサー
- Java
- javaのsocketインスタンスについて
javaでソケット接続するプログラムを作成しています。 socketを.closeした場合、このsocketインスタンスのシステムリソースは開放されるのでしょうか? お詳しい方おられましたらよろしくお願いします。
- 締切済み
- Java
- Socket通信での通信異常について
JavaでSocket通信している状態で、物理LANを抜いたりして通信異常状態を起こしても、すぐには通信異常と検知できないようで、一定期間してからSocketExceptionなどを検知します。 現在、クライアントとサーバで常に受信し続け、各々で1秒毎にSocketでメッセージを相互に送っております。 その間で物理LANを抜いても、一定期間は送信しつづけるように見え(実際受信はされていない)、 一定時間を超えると、上記のようにSocketExceptionで例外検知します。 上記のようにSocket通信で通信異常状態の場合には即検知することは無理なのでしょうか?
- ベストアンサー
- Java
- JavaのSocketを使い、チャットシステムを作っています。
JavaのSocketを使い、チャットシステムを作っています。 2ちゃんねるの掲示板やニコニコ動画のコメントの真似のようなものです。 一つのサーバーに、複数のクライアントがアクセスしてコメントを書いていくというものです。 しかしオブジェクトの送受信で困ったことになりました。 //読み込み BufferedInputStream bis = new BufferedInputStream(socket.getInputStream()); ObjectInputStream ois = new ObjectInputStream(bis); //書き込み BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream()); ObjectOutputStream oos = new ObjectOutputStream(bos); こうするとBufferedOutputStreamの実体化でプログラムがフリーズしてしまいます。 oisで一度なにかを読み込んだあとに実体化すればできるのですが、 マルチスレッドプログラミングを使うため、 接続があった瞬間に両方実体化しなくてはいけません。 socketからStreamを手に入れることが、一度入出力をするまで片方しかできないようです。 socketのcloneを実体化することも考えたのですが、サーバー側は serverSocket.accept()を使うためかうまくできません。 どうすればいいのでしょうか。 デバッガの領域からはずれた部分(接続、送受信等)のバグ探しで非常に滅入っています。 助けてください。お願いします。
- 締切済み
- Java
- Socketの使用方法について
Socketの使用方法について サーバ側クラスA クライアント側クラスB とあり、Aは常駐しておりBから接続が合った場合に処理を行い、 処理後には待機状態に再び戻ります。 上記の場合に Aのクラスは以下のように作成しましたが、★の部分でCloseではなく、このままこのソケットを使用して待機したいです。 (ほぼ同時刻に複数のアクセスがあるため、資源の事を考えて使いまわしたいです。) どのような手段があるのかご指導お願い致します。 又、そもそもソケットに関しての理解が足りないとも思いますので、参考サイトを教えていただけると幸いです。 クラスA ServerSocket svsock = new ServerSocket(port); while (true) { Socket socket = svsock.accept(); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); BufferedWriter out = new BufferedWriter(new PrintWriter(socket.getOutputStream(), true)); // 処理結果を受信 String line; if ((line = in.readLine()) != null) { System.out.println("受け取ったメッセージ : " + line); out.write("サーバで表示。"); out.newLine(); out.flush(); } socket.close(); // ★ }
- ベストアンサー
- Java
- パッケージ管理に変更されたデータObjectのリカバリー方法
今までパッケージ管理されていなかったデータオブジェクトをパッケージ管理するよう変更したのですが、クラス名が変更されたことにより旧データオブジェクトの復旧が行えなくなりました。 前データ) class Data implements Serializable { public Data(){} } (1)オブジェクトストリームとしてExport。 Data target = new Data(); java.io.FileOutputStream ostream = new java.io.FileOutputStream("C:\\test.data"); java.io.ObjectOutputStream p = new java.io.ObjectOutputStream(ostream); p.writeObject(target); p.flush(); ostream.close(); (2)Dataオブジェクトをパッケージ管理に変更 新データ) package com.corp.etc class Data implements Serializable { public Data(){} } (3)(1)でExportしたデータをImport java.io.FileInputStream istream = new java.io.FileInputStream("C:\\test.data"); java.io.ObjectInputStream p = new java.io.ObjectInputStream(istream); Object obj = p.readObject(); istream.close(); Data data = (Data)obj; (3)の実行結果) java.lang.ClassNotFoundException: Data クラス名が変わったので、当たり前の動きとは思うのですが、旧データを今までと同じようにインスタンス化するために何か良い方法はありませんでしょうか?
- 締切済み
- Java
- Socket + XML
・クライアントはサーバへXML形式のクエリを送信し、 ・サーバからXML形式のデータを受け取る という単純なプログラムを実装しています。 しかしサーバ側の、InputStreamを引数とするXMLパースメソッドでwaitしてしまって困っています。 かといって、クライアント側のOutputStreamを閉じると、クライアントのソケット自体も閉じてしまいます。 なるべく一度のコネクションで送受信を終了させたいのですが、よい方法はないでしょうか? 一応、BufferedReaderを利用してXML文章を文字列に落としてから StringReaderをbuilder.parseの引数に与えることで解決出来てはいるのですがスマートではない気がしまして。 [Server側] ServerSocket server_sock = new ServerSocket(12345); Socket sock = server_sock.accept(); /* XMLパーサビルダ生成 */ DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = fact.newDocumentBuilder(); /* ドキュメント docIn の解析 */ Document docIn = builder.parse(sock.getInputStream());//ここから動かない(clientがoutputを終了するまで待っている?) (略) /* 結果ドキュメント docOut の構築*/ Document docOut = builder.newDocument(); (略) /* docOut 送信 */ TransformerFactory tfactory = TransformerFactory.newInstance(); Transformer transformer = tfactory.newTransformer(); transformer.transform(new DOMSource(docOut), new StreamResult(sock.getOutputStream())); sock.getInputStream().close(); sock.getOutputStream().close(); sock.close(); [Client側] Socket sock = new Socket("localhost", 12345); /* XMLパーサビルダ生成 */ DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = fact.newDocumentBuilder(); /* クエリドキュメント docOut の構築*/ Document docOut = builder.newDocument(); (略) /* docOut 送信 */ TransformerFactory tfactory = TransformerFactory.newInstance(); Transformer transformer = tfactory.newTransformer(); transformer.transform(new DOMSource(docOut), new StreamResult(sock.getOutputStream())); sock.getOutputStream().flush(); //sock.getOutputSream().close();//これにすると、socketが閉じてしまう /* 結果ドキュメント docIn の解析 */ Document docIn = builder.parse(sock.getInputStream());//サーバから結果が送信されないので、クライアントはここで停止 (略)
- ベストアンサー
- Java
- Cliant から Server の Socket 管理
サーバアプリを作成しています。 ServerSocket を生成してから 基本的に read() でクライアントからの データを待機しています。 その状態でクライアント側から close 処理を行いたいのですが どういう形にすれば正しく終了できるのでしょうか? クライアントから Socket の close() を行うと 空のデータが2回送られてきます。 例外が発生しているので finally で close させようと 思ったのですがビルドエラーになります。 どうかご教授お願いします。
- ベストアンサー
- Java