- - PR -
ソケットの送信処理でフリーズ
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2006-09-04 19:44
お世話になります。
ソケット(TCP)通信を行うプログラムの送信処理で、プログラムが停止してしまいます。 処理は「Listen→Accept→受信→応答送信→相手切断を待つ→切断」を繰り返し行うという内容です。 毎回発生するわけではなく、何日間か稼動させていると発生します。 原因がまったく分からず困っています。 みなさんのお力お借りしたいです。 OSはLinuxです。 Javaのバージョンは、1.4.1_02です。 よろしくお願いします。 //----------------------------------------------------------------------------------------------- public abstract class SocketBase{ private ServerSocket m_srvSock = null; private Socket m_clntSock = null; private InputStream m_sockIn = null; //入力用ストリーム private OutputStream m_sockOut = null; //出力用ストリーム public void listenSock(int iPortNo) throws Exception{ m_srvSock = new ServerSocket(iPortNo); m_srvSock.setSoTimeout(3000); } public void acceptSock(int iTimeOut) throws Exception{ m_clntSock = m_srvSock.accept(); m_srvSock.close(); // サーバソケットをクローズ m_clntSock.setSoTimeout(iTimeOut); m_sockIn = m_clntSock.getInputStream(); m_sockOut = m_clntSock.getOutputStream(); } public void receiveSock(String encode){ int rcvsize = 0;//受信Byte数 try { rcvsize = m_sockIn.read(readbuf); }catch(Exception e){ } } public void sendSock(String cmd, String encode){ try { //送信 m_sockOut.write(cmd.getBytes(encode)); m_sockOut.flush(); } catch (Exception e) { } } } public class ReceiveSock extends SocketBase implements Runnable{ public void run() { // アプリケーション終了までループ while(**){ // Listen super.listenSock(ポート番号); // Accept super.acceptSock(3000); // 切断されるまでループ while(true){ super.receiveSock(m_encode);// 受信 if(**){ // 受信成功 super.sendSock("応答電文"); // ●●ここで止まってしまいます }else{ // 切断された場合 break; } } super.disconnect();// 切断 } } } //----------------------------------------------------------------------------------------------- | ||||
|
投稿日時: 2006-09-04 21:17
多分デッドロックしているんでしょうね。95%くらいの確率。(ここもイイカゲン)
スレッドダンプして調べてみましょう。 スレッドダンプでググッたら@ITがヒットしますよ。 解説が長いので、ここでは省略しますが それを見てわからなければ悩みましょう。 | ||||
|
投稿日時: 2006-09-04 22:04
log4Jで良いと思うんですが、トレースログとか出力
した方がいいんのではないですかね。 あと、
は、トラブルの情報を闇に葬るブラックホールになるの ではないですかね。 | ||||
|
投稿日時: 2006-09-05 07:55
うえださん、小僧さん ありがとうございます。
>小僧さん 小僧さんにご指摘いただいた点については、実際には対応しています。 ソースコードを提示する際に、読みにくくなるかと思い、割愛しました。 一言書いておけば良かったです。申し訳ないです。 >うえださん スレッドダンプについて調べてみました。 今回の現象の調査にはとても有効な方法だと思いました。 参考になりました。ありがとうございます。 ただ、スレッドダンプは、実際に現象が発生した時に行うものだと思いますが、 今回の現象は発生頻度も低く、またタイミングもよめないため、 現象が発生するまで待つというのは難しいかもしれません・・・。 他になにか調査する方法はないでしょうか? よろしくお願いします。 | ||||
|
投稿日時: 2006-09-05 08:24
JDKのバージョンアップはできないのでしょうか?
とりあえず別のバージョンを入れて動かして見るとか。 ちなみにSoket関連では以下のバグ報告があります。 http://java.sun.com/products/archive/j2se/1.4.1_07/ja/ReleaseNotes.html 4680160 :java.net.ServerSocket.implAccept で JVM がクラッシュする 4674826 :java.net.Socket のコンストラクタからセキュリティ例外がスローされる | ||||
|
投稿日時: 2006-09-10 22:02
なぜ受信後の送信処理に問題があると判断したか不明ですが
プログラムを実行しているサーバ側かクライアント側で TCP/IPのパケットダンプととってみては? | ||||
|
投稿日時: 2006-09-11 13:44
いっきゅうさん ご返信ありがとうございます。
JDKの1.4.1_02と1.4.1_07のソースを見比べてみましたが、 PlainSocketImplクラスのclose()に変更が行われており、 非ブロッキング中の切断は、2段階で行われるようになっていました。 このあたりの変更は、ちょっとだけ今回の不具合と関係ありそうな気がもしますが、 確信が持てません。 でも、試してみる価値はありそうな気もします。 検討してみます。 ありがとうございます。 | ||||
|
投稿日時: 2006-09-11 13:47
ご返信ありがとうございます。
送信処理に問題があると判明したのは、 super.sendSock()を呼び出す前と後に、ログを出力するようにしたところ、 呼び出す前のログは出力されていましたが、 呼出し後のログは出力されていませんでした。 このことから、送信処理で停止していると判断しました。
これは、ネットワーク的なトラブルを疑ってみろということでしょうか? |