Perlでタイムアウト付きIOアクセスをするには
[上に]
[前に]
[次に]
Cz
1999/08/05(木) 21:00:42
Windows環境でのPerlでタイムアウト付きIOアクセスをする方法はないものでしょうか?。
たとえば、socketで、5秒のタイムアウト付きReadinをして、
メッセージがなければタイムアウトして他の処理へ、といった処理を、
fork無しでやりたいのですが。
ついでといってはなんですが、もう一つ。
windowsのtelnetやTeraTermで、telnet以外のポートを
叩いたときに、コネクトはするのですが、メッセージ表示も、
入力も受けつけなくなるのはどうしたら良いのでしょうか?。
Unixのtelnetからだと問題無いのですが・・・。
Cz
1999/08/05(木) 21:08:33
追加です。
具体的には、コンソール入力と、ソケットからのメッセージを、
fork無しでタイムシェアリングしながら監視するプログラムを
考えてます。
(それ以外でもタイムアウト付きアクセス使いたいのですが、とりあえず。)
B-Cus
1999/08/06(金) 18:11:29
> Windows環境でのPerlでタイムアウト付きIOアクセスをする方法はないものでしょうか?。
eval {
alarm(10);
$buf=<SOCKET>;
alarm(0);
}
if ( $@ =~ /タイムアウトが起こったかどうかわかるような文を書く/
タイムアウトになった
}
ただし Windows でできるかどうかは知りません。
> 具体的には、コンソール入力と、ソケットからのメッセージを、
より一般的には(4引数の方の)selectを使うと思います。
> windowsのtelnetやTeraTermで、telnet以外のポートを
これかな?
http://www.cs.gunma-u.ac.jp/~j5306050/net/win-telnet.html
B-Cus
1999/08/06(金) 18:20:39
う、抜けてた。
$SIG{ALRM} = \&timed_out;
sub timed_out {
die 'TIMED OUT';
}
eval {
alarm(10);
$buf=<SOCKET>;
alarm(0);
}
if ( $@ =~ /TIMED OUT/ ){
タイムアウトになった
}
ってことです。O'REILLY の「実用Perlプログラミング」って本に載ってます。
> http://www.cs.gunma-u.ac.jp/~j5306050/net/win-telnet.html
これ、記述内容に自信がないので(特にWindowsのとこ)、もし間違ってたら
教えてください。
ふじ
1999/08/06(金) 19:57:52
残念ながら・・・
> The Unsupported function alarm function is unimplemented
ということで。
Windows版の Perl には alarm 関数が実装されていないようです。
#NT4.0 SP3, Perl 5.005_03(ActivePerl Build 517) で確認。
代替手段があったら私も知りたい・・・
Cz
1999/08/06(金) 20:07:44
Telnetの件、参照先WWWページを見て解決しました。ありがとうございます!
さて、タイムアウト付きの方ですが・・・
SIGNAL自体が実装されていません :-)
引き続き情報お待ちしております。
(私自身もあっちこっち探している最中ですが)。
とほほ
1999/08/06(金) 23:30:01
B-Casさんの回答にもありましたが、タイムアウト処理は、引数が4つ
ある方のselect()を用いることで実現できると思います。
B-Cus
1999/08/07(土) 06:38:32
えっと、とほほさんには2・3回間違えられてるような気がしますが、
B-CasではなくB-Cusです :-)
B-Cus
1999/08/07(土) 07:02:27
4引数selectの使い方は、青ラクダ本にばっちり載ってます。
ところで、青ラクダ本のselectの項に、
「この関数を使うとポーリングを避けることができる」
とありますが、一般的なポーリングってどうやるんですか?
fseekで最後に移動して、前回の場所と変わってたらその分を読む?
それとも lseek?
そもそも(ファイルディスクリプタ経由でアクセスできるとはいえ)、
socket に対してポーリングできるのかな?
B-Cus
1999/08/07(土) 10:09:16
> 一般的なポーリングってどうやるんですか?
ファイルに対しては、
use FileHandle;
$|=1;
$fh = new FileHandle;
$fh->open("./hoge");
while (1){
print <$fh>;
$fh->clearerr;
}
でいけるみたい。seekでもできそうな感じ。ソケットとの絡みは
よくわかりませんでした。
ちなみに4引数socketによるタイムアウトの使い方はここ。
http://www.kt.rim.or.jp/%7ekbk/perl5.005/perlipc.html#UDP_Message_Passing
ただし
http://www.kt.rim.or.jp/%7ekbk/perl5.005/perlwin32.html#BUGS_AND_CAVEATS
四引数の select() 呼び出しは、ソケットに関してのみサポートさ れています。
なので、STDINを監視するのは無理かもしれません。この際、Windowsなんて捨てちゃえ。
とほほ
1999/08/10(火) 11:28:32
> えっと、とほほさんには2・3回間違えられてるような気がしますが、
> B-CasではなくB-Cusです :-)
ごめんなさい。大変失礼を・・・(^^;)
> 一般的なポーリングってどうやるんですか?
UNIXのソケット関数だと、getsockopt()だかioctl()だかで、現在の
受信バッファ中のデータサイズを知ることができたので、これを定期
的にチェックする・・・ということかも・・・。
Cz
1999/08/17(火) 15:34:01
レス頂いた皆様、どうもありがとうございます。
さて、私は・・・・
結局、4変数のselectを使ってsoketをタイムアウト付き
アクセスし、コンソールに対して(win32では4変数socketは
未サポート)、タイムアウト付きアクセスできませんので、
ローカル(127.0.0.1)にループバックさせて、
2つのソケットに対してのタイムアウト付きアクセスで
解決させました。
個人的にはwindows環境捨てちゃえという意見、賛成なのですが :-P
今後も何か情報ありましたらお願いします。
Cz
1999/08/17(火) 15:35:10
訂正。
> win32では4変数socketは
win32では4変数selectは、
の間違いです。
[上に]
[前に]
[次に]