JavaでSocket通信をしようとおもっています。
Socketはnewするときにconnectもしてしまいまうらしいので
妙なIPアドレスを指定したりして、応答がもどってこないと
すべてそこで止まってしまうとおもうのですが、
Timeoutをかける方法はないのでしょうか。
setSoTimeoutというメソッドはreadのときとかStreamに関してしか
かけられないということが分かりました。

Socketのコンストラクタの引数にSocketImplを指定して、
Socket.setSoTimeoutしてから
SocketImpl.connectすれば大丈夫かな、とおもっていたのですが、
setSoTimeoutはreadにしか効かない、と明記してあったので、無駄ですよね。

どこかに情報がないかと検索エンジンでも探してみたのですが、
見つかりません。もしかしてタイムアウトを設定するのは
一般的な方法ではないのかとも思えてきました。
ずーーーーっと接続にしにいくのを待ちつづけるしかないのでしょうか。

どのような設計(というか使うクラス?)をするべきなのか、
思い当たるかたがいらっしゃいましたら教えていただけないでしょうか。

よろしくお願い致します(__)

このQ&Aに関連する最新のQ&A

A 回答 (2件)

 以下は、別のスレッドでクライアントソケットを作って、それを監視/制御する一例です。


以前にそのような状況になったときがあり、そのときは以下の方法で対処できたと思います。
ありえないアドレスなどを指定して、ソケットを作るところで止まってしまったときには、
ソケットを作ろうとしたスレッドごと放棄しています。

import java.net.*;

class clientthread extends Thread {

private Socket Client;
private ServerSocket Server;
public boolean ConnectionFlag, BreakFlag;
private int Port;
private String HostName;

public clientthread(String name, int port) throws Exception { super();
Port = port;
HostName = name;
ConnectionFlag = false;
BreakFlag = false;
};

public String GetConnectionData() {
if (!ConnectionFlag) return("NotConnected");
return(Client.getRemoteSocketAddress().toString() + " : " + Integer.toString(Client.getLocalPort()));
};

public void run() {

try {

Client = new Socket(InetAddress.getByName(HostName), Port);
ConnectionFlag = true;
if (BreakFlag) return;

} catch(Exception ex) { System.out.println("<run>" + ex.toString()); };

};

}

public class clientto {

private static final int TimeoutTime = 10;

public static void main(String args[]) {

int i, j;
clientthread ClientThread;

try {

for (j = 0; j < args.length; j += 2) {

System.out.println(args[j]);
ClientThread = new clientthread(args[j], Integer.parseInt(args[j + 1]));
ClientThread.start();

for (i = 0; i < TimeoutTime; i ++) {
if (ClientThread.ConnectionFlag) break;
System.out.println("Connecting.." + i);
try { Thread.sleep(100); } catch(Exception e) {};
};

if ((i == TimeoutTime) && (!ClientThread.ConnectionFlag)) ClientThread.BreakFlag = true;
else ClientThread.join();
System.out.println(ClientThread.GetConnectionData());

};

} catch (Exception ex) { System.out.println("<main>" + ex.toString()); };

System.exit(0);

};

}
    • good
    • 1

Java は、あまり詳しくないので、考え方だけ。



ソケット通信をするクラスで、実際に connect するメソッド以外に、
タイムアウトをかけるメソッドを用意して、スレッドとして動かします。

Socket は、そのメソッドからも参照できるようにメンバーにして。

一定時間過ぎたところで、その Socket に対して close() をすると、
connect() 中でも、例外が飛んでくるはず。

正常に connect() できたのであれば、スレッドを止めるか、Socket を
close() しないでちょうだいね、という情報をメンバーに設定する。


って感じではどうでしょうか?

# java はあまり詳しくないですが、一応、ソフト屋さんです。
# 考え方はあっているはず。
    • good
    • 0
この回答へのお礼

ありがとうございます。
やはりスレッドにして自力で実装しなくてはならないのですね…。
みんなやるから既にメソッドか
テクニックが公開とかされていないものかな、
とおもったのですが、見つけられなくて…。
ありがとうございます。自分で組み込んで見ます(__)

お礼日時:2001/07/07 11:04

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qselect(ソケット)

ソケットを用いてプログラミングしていると、よく出てくると思うのですが、次の意味を教えてください。
select(SH); $| = 1; select(STDOUT);
$|(特殊記号)やSTDOUTなど、なるべる細かく教えて頂けると幸いです。
よろしくお願いします。

Aベストアンサー

ソケットは効率的な処理をするために通常はバッファリングするモードになっています。
(その都度処理するよりある程度やりとりするデータが溜まってまとめてやったほうが効率的)

これを回避(フラッシュ)したいときにselect(SH)のように
ソケットを選んで$|=1 でフラッシュモードに切り替えています。
詳しくないのですがプログラミングにおいてフラッシュが用いられるのは、ソケット通信で双方向にやり取りするときが多いと思います。
ちなみにソケットをclose(SH)すると自動的にフラッシュしてくれます。

また、デフォルトではSTDOUTが選択状態になっていますので
> print "hello.\n";

> print STDOUT "hello.\n";
の省略形というわけです。

余談ですが、Perl使いは面倒くさがりが多いので慣用句みたいに
> select((select(SH),$|=1)[0]);
と、まとめて書く人もいます。
これはselectが返す値が直前まで選択されていたソケットだからできる技です。

ソケットは効率的な処理をするために通常はバッファリングするモードになっています。
(その都度処理するよりある程度やりとりするデータが溜まってまとめてやったほうが効率的)

これを回避(フラッシュ)したいときにselect(SH)のように
ソケットを選んで$|=1 でフラッシュモードに切り替えています。
詳しくないのですがプログラミングにおいてフラッシュが用いられるのは、ソケット通信で双方向にやり取りするときが多いと思います。
ちなみにソケットをclose(SH)すると自動的にフラッシュしてくれま...続きを読む

Qコンストラクタの問題がわかりません。

自分で考えたり、調べたりしながら自分なりの答えを作ってみたのですが、どうも間違っているようです。
あとどこを修正すればいのか教えてください。
よろしくお願いします。

Vendingクラスを,飲み物の値段を表現するクラス変数priceを使うように書き直しなさい。
また、メソッドpushの返り値をbooleanにして、
買うことができたらtrue,出来なかったらfalse
を返すようにしなさい。

import java.io.*;

class testV{
public static void main(String arg[]){
BufferedReader input=
new BufferedReader(new InputStreamReader(System.in));

Vending v=new Vending();

String line;
try{
System.out.print("投入する金額を入力(マイナスなら終了)");
while((line=input.readLine())!=null){
int mon=Integer.parseInt(line);
if (mon < 0) {
break;
}
System.out.println("==>"+mon);
v.enter(mon);
v.push();
System.out.print("投入する金額を入力(マイナスなら終了)");
}
}catch(IOException e){
}
}
}

自分で考えたり、調べたりしながら自分なりの答えを作ってみたのですが、どうも間違っているようです。
あとどこを修正すればいのか教えてください。
よろしくお願いします。

Vendingクラスを,飲み物の値段を表現するクラス変数priceを使うように書き直しなさい。
また、メソッドpushの返り値をbooleanにして、
買うことができたらtrue,出来なかったらfalse
を返すようにしなさい。

import java.io.*;

class testV{
public static void main(String arg[]){
BufferedReader input=
...続きを読む

Aベストアンサー

では,次のようになると思います.

public class Vending {
static int price = (飲み物の値段);

(中略)

public void enter(int money) {
(お金の投入時の処理)
}

public boolean push() {
if(買える) { // この判定にpriceを使用
(買ったときの処理)
return true;
} else {
(買えないときの処理)
return false;
}
}
}

QTCP/IPプログラミングでのselectについて

selectは使用しているソケットのディスクリプタを登録させれば、send、writeシステムコールからのデータの受信等は検知しますよね。
では、コネクション要求(connect)は、検知するのでしょうか?
どなたか回答よろしくお願いします。

Aベストアンサー

もちろん検知しますよ。
LISTENしているソケットに対しての要求を検知したら
acceptしてやればOKです。

QAndroid Socket.connectエラー

Androidでソケット通信するプログラムを作っています。

PC側がソケットサーバーをたてて(accept)、
Android側でクライアントとして接続(connect)するようにしています。

connectを実行している部分のソースは以下のようにしています。

-----------------
String ip = "192.168.XX.XX"; <-PCのIPアドレス
int port = 9999;

socket = new Socket();
InetSocketAddress addr = new InetSocketAddress(ip, port);
try{
socket.connect(addr);
return true;

}catch(IOException e){
e.printStackTrace();
return false;
}
------------------

上記やり方でまずはエミュレータで試したところうまく行きました、その後
実機に入れて同じように実行したところconnectのところで例外が飛んできます。
メッセージは"no route to host"でした。

実は全く同じソースで以前は実機でもできていたはずなんですが、
最近試したところできなくなっているようでした。

Android端末はXperia Arcですが、OSを2.3.4にバージョンアップしたことくらいで
以前と特に変わったところはないと思うのですが

原因として何が考えられるでしょうか?
よろしくおねがいします。

Androidでソケット通信するプログラムを作っています。

PC側がソケットサーバーをたてて(accept)、
Android側でクライアントとして接続(connect)するようにしています。

connectを実行している部分のソースは以下のようにしています。

-----------------
String ip = "192.168.XX.XX"; <-PCのIPアドレス
int port = 9999;

socket = new Socket();
InetSocketAddress addr = new InetSocketAddress(ip, port);
try{
socket.connect(addr);
return true;

}catch(IOException ...続きを読む

Aベストアンサー

無線LANで接続してないからですよ。

通常はUSBでの通信はフラッシュメモリと同じ扱いなので。

もし本当にUSBで以前できたなら擬似ロケーションの設定等をみてください。

Qselectの意味

selectの意味

リファレンスマニュアルと本のselectの説明がわかりません。
説明の文はなんとかわかるのですが、引数のとり方が「reads[, writes[, excepts[, timeout]]]」となっていて、これは 3 要素の配列を返しているように見えないので、混乱します。「reads[, writes[], excepts[], timeout[]」という書き方なら3 要素の配列を返していると納得できるのですが、ここで返しているのはreadsの中にwritesがあり、更にその中にtimeoutがある配列を返しているんでしょうか?

手元の本に「selectはリクエストを受信すると、リクエストを検出したソケットだけをリストに返します。」とあるのですが、ここで言うソケットとは入力、出力、例外を指していて、リストというのはつまり配列のことなんでしょうか?

Aベストアンサー

a = hoge.select(ARGS)

の場合に、ARGSの部分が引数です。
ここは、「reads[, writes[, excepts[, timeout]]]」とかかれているので
以下の4種類の書き方ができます。
hoge.select(reads, writes, excepts, timeout)
hoge.select(reads, writes, excepts)
hoge.select(reads, writes)
hoge.select(reads)

また、aに代入される値が戻り値です。
ここには、
「戻り値は、timeout した時には nil を、そうでないときは 3 要素の配列を返し、その各要素が入力/出力/例外待ちのオブジェクトの配列です(指定した配列のサブセット)」
と書かれているので
nil 若しくは [???,???,???]の形で値が代入されます。

これでご理解いただけるのではないでしょうか。

Qコンストラクタの引数の中のnew?

はじめまして☆
java初心者ですが、意味がわからなくて困っています。
オブジェクトをnewする時、たまにコンストラクタの引数部分に
newの記述がある時があるのですが、これはどういう意味でしょうか?
(何のオブジェクトを作成しているのでしょうか?)
よかったら、教えてください。

Aベストアンサー

例をあげて、説明してみます。

---------- Sample.java ----------
1:class A {
2: public A() {
3: System.out.println("A#A() -- START");
4: System.out.println("A#A() -- END");
5: }
6:}
7:
8:class B {
9: public B(A param1) {
10: System.out.println("B#B(A param1) -- START");
11: System.out.println("B#B(A param1) -- END");
12: }
13:}
14:
15:public class Sample {
16:
17: public static void main(String[] args) {
18: System.out.println("Sample#main(String[] args) -- START");
19:
20: B instance1 = new B(new A());
21:
22: System.out.println("Sample#main(String[] args) -- END");
23: }
24:
25:}
26:
---------- Sample.java ----------

この例だと、
> 20: B instance1 = new B(new A());
の部分がコンストラクタの引数に new を使用しています。

これは、BクラスのB(A param1)と言うコンストラクタに、
Aクラスのインスタンスを渡していると言う事です。

new A()の部分で、Aクラスのコンストラクタを呼び出して、インスタンスを生成してます。

例をあげて、説明してみます。

---------- Sample.java ----------
1:class A {
2: public A() {
3: System.out.println("A#A() -- START");
4: System.out.println("A#A() -- END");
5: }
6:}
7:
8:class B {
9: public B(A param1) {
10: System.out.println("B#B(A param1) -- START");
11: System.out.println("B#B(A param1) -- END");
12: }
13:}
14:
15:public class Sample {
16:
17: public static void main(String[] arg...続きを読む

Qソケットプログラミングで・・

簡単なソケットプログラムを作ろうとしておりまして、サイトで調べたりしておりましたところ、なんとか分かってきたのですが、ひとつどうしてもわからないことがありますので教えていただけますでしょうか。
ソケットから受信するメッセージの生成のところなんですが、
「WSAAsyncSelect(m_socket,m_hWnd,WM_USER_ASYNC_SELECT,FD_READ | FD_WRITE)」
で、2番目の引数「m_hWnd」がわかりません。
教えていただけないでしょうか?よろしくお願いします。

Aベストアンサー

こちらの「III.非同期ソケット通信」のところが参考になりませんか?
WSAAsyncSelect()で、例えば受信データありの場合にイベントとして通知する
ウィンドウのハンドルをここに記述しておき、そのウィンドウのイベント
ハンドラで受信処理を行なうようなプログラミングを可能にします。
http://yonex1.cis.ibaraki.ac.jp/~yonekura/2002kadai/lecture03.html

参考URL:http://yonex1.cis.ibaraki.ac.jp/~yonekura/2002kadai/lecture03.html

QdjUnit コンストラクタがprivateでテストが行えない

djUnit コンストラクタがprivateでテストが行えない

djUnitを使っております。

テスト対象のメソッドにアクセスしてテストを行いたいのですが、
どうもそれができません。
理由としては、コンストラクタがprivateになっているから?です。
(「コンストラクター TestManager() は不可視です」というエラーが出ます。)

コンストラクタのprivateを消せば、テスト対象のメソッドにアクセスできるのですが、
実際には消してテストをしてはだめということになっています。

コンストラクタがprivateでもdjUnitでテストが行える方法がございましたら、
書き方をご教授いただけないでしょうか?
どうかよろしくお願いいたします。


一応下記が詳細です。
(クラス名、コンストラクタ名、メソッド名)
------------------------
[クラス]
public final class TestManager
[コンストラクタ]
private TestManager() {
}
[テスト対象のメソッド]
public Structure testCreate(byte[], byte[], byte[])
-----------------------

色々試したのですが、途中で終了してしまって
目的のテスト対象のメソッドを実行するところまで辿りつけません・・・。
[お試しパターン1]
Class c = TestManager.class;
Constructor[] con = c.getDeclaredConstructors();
TestManager conIns = (TestManager)con[0].newInstance(); //ここで処理が終了してしまう
[お試しパターン2]
Class testClass = Class.forName("TestManager"); //ここで処理が終了してしまう
Constructor[] TestManager = testClass.getDeclaredConstructors();
TestManager[0].setAccessible(true);
Object conIns = TestManager[0].newInstance((Object[])null);
TestManager test = (TestManager)conIns;

djUnit コンストラクタがprivateでテストが行えない

djUnitを使っております。

テスト対象のメソッドにアクセスしてテストを行いたいのですが、
どうもそれができません。
理由としては、コンストラクタがprivateになっているから?です。
(「コンストラクター TestManager() は不可視です」というエラーが出ます。)

コンストラクタのprivateを消せば、テスト対象のメソッドにアクセスできるのですが、
実際には消してテストをしてはだめということになっています。

コンストラクタがprivateでもdjUnitでテ...続きを読む

Aベストアンサー

こんにちは。

済みません・・・、さっぱり意味がわかりません。
>testCreate(fileA, fileB, fileC);
どこから呼べるの???
TestManagerクラスからは呼べるだろうけど、外部からは呼べない。
TestManagerが内部的に使うだけの目的で作ったpublic関数なら、単独ではテストの仕様がない。
それだったら
public Structure testCreate(byte[], byte[], byte[])
がそもそもおかしいという話になるが・・・。

例えば
public TestManager getInstance(){return new TestManager();}
とか無いの?

Qint select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)について

見当違いな質問かもしれませんがお願いします。

複数のソケットを監視する際にselectを使う場合のことですが、
selectの動作と戻り値について疑問があります。

http://www.linux.or.jp/JM/html/LDP_man-pages/man2/select.2.html
ここを参照すると、selectの戻り値は
「更新された 3 つのディスクリプタ集合に含まれているディスクリプタの数 (つまり、 readfds, writefds, exceptfds 中の 1 になっているビットの総数) を返す。」
とあります。
私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識だとreadfds,writefdsが引数として与えられているとしても、
どちらかのfd_setのうち、一つでも動きがあればselect文は
抜けてしまうことになります。とすると、戻り値として
「readfds, writefds, exceptfds 中の 1 になっているビットの総数」
は常に1ということになってしまいます。しかし、総数というからには
複数同時に1になることもあるはずです。

私の認識が間違っているとは思うのですが、どう間違っているのかわかりません。
select文の動きについて詳しく教えていただけないでしょうか。
または良いページがあれば教えてください。

見当違いな質問かもしれませんがお願いします。

複数のソケットを監視する際にselectを使う場合のことですが、
selectの動作と戻り値について疑問があります。

http://www.linux.or.jp/JM/html/LDP_man-pages/man2/select.2.html
ここを参照すると、selectの戻り値は
「更新された 3 つのディスクリプタ集合に含まれているディスクリプタの数 (つまり、 readfds, writefds, exceptfds 中の 1 になっているビットの総数) を返す。」
とあります。
私の中でselectは登録してあるFDのうち、一つでも動きが...続きを読む

Aベストアンサー

>私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識はあっています。
しかし、selectを呼び出す以前にOKになっているFDがあれば、それらは全てビットがONになります。

話しを簡単にする為に、受信のみのソケットを3つ作成したとします。
これらの3つのソケットに向けて相手が電文を送ったとします。
その状態でまだ、こちらはselectを呼び出さずにいます。しばらくしてから、selectを呼び出すと、selectは即座にリターンし、3つのビットが一度にONになっているはずです。
一方、相手が、一切電文を送ってない状態で、selectを呼び出した場合は、何れかのビットがONになればリターンするので、そのときは、貴方が想像しているように
ビットの総数は1になる可能性が高いです。
従って、相手が電文を送る前にselectを呼び出すか、送った後にselectを呼び出すかは、その時のタイミングにより異なります。従って、ビット数の総和が常に1であるとは、考えない方が無難です。(1つのソケットしか使用しない場合は別ですが・・・)

>私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識はあっています。
しかし、selectを呼び出す以前にOKになっているFDがあれば、それらは全てビットがONになります。

話しを簡単にする為に、受信のみのソケットを3つ作成したとします。
これらの3つのソケットに向けて相手が電文を送ったとします。
その状態でまだ、こちらはselectを呼び出さずにいます。しばらくしてから、selectを呼び出すと、selectは即座にリターンし、3つのビ...続きを読む

Q計算してからコンストラクタに渡すか

メインクラスAからクラスBをインスタンス化します。
Bクラスが持つ変数Cには1~100までの数値がランダムで入ります。

ここで、AクラスであらかじめCを計算しておいてBクラスのコンストラクタに引数として渡すのか

それともAクラスではBクラスを生成するだけで、
Bクラスのコンストラクタ内で変数Cの値を計算するのか

どちらが良いでしょうか?
お教えください。

Aベストアンサー

場合による、と思います。

自分なら、本当にここに書いてある事柄だけならBのコンストラクタでCをランダム計算するように組みます。特に、Cの値をAが知っていてはいけない場合はCの値のゲッターすら作りません。

しかし、Aが全体的にCの値を何らかの形で管理する必要がある場合は、AでCをランダム計算して管理処理してBのコンストラクタに渡します。
あるいは、擬似乱数計算のアルゴリズムを変更できるようにするならば、そのアルゴリズムインターフェースを作って、そこからランダム値Cを取り出してBのコンストラクタに渡します。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング