Perl の select システムコールでよく分からないことがあるので,お尋ねします
.
クライアントからの接続を select で待ち受けて処理しようとしていますが,
新しい接続を accept で受けても,帰ってくるファイルハンドルが1回目と同じに
なってしまいます.そうではなくて,クライアント間のやりとりを仲立ちするよう
な
プログラムを作りたいのです.
ソースの一部を下記に添付します.
どなたか分かる方がいらっしゃいましたら教えてください.
よろしくお願いします.
--- midiCity Co.,Ltd. -------------------------------------------------->
関戸 良一 rse...@midicity.co.jp
SEKIDO Ryoichi Phone/Fax 03-5478-0821/5478-0820
<-------------------------------------------------- midiCity Co.,Ltd.----
$thisport = pack($sockaddr, &AF_INET, $port, "\0\0\0\0");
socket(S, &PF_INET, &SOCK_STREAM, $proto) ||
die "Cannot create socket";
bind(S, $thisport) ||
die "Cannot bind socket";
listen(S, 5) ||
die "Cannot listen socket";
$rmask1 = '';
$rmask2 = '';
vec($rmask1, fileno(S), 1) = 1;
$rmask2 = $rmask1;
undef $list_fd1;
undef $list_fd2;
while (select($rmask2, undef, undef, undef) > 0) {
for ($fd=0; $fd<$fd_setsize; $fd++) {
if (vec($rmask2, $fd, 1) != 1) {
next;
}
if ($fd == fileno(S)) {
# このaccept で NS が常に同じになってしまう.
accept(NS, S) ||
die "Cannot accept";
vec($rmask1, fileno(NS), 1) = 1;
if (! $list_fd1) {
$list_fd1 = NS;
}else{
$list_fd2 = NS;
}
}
# 以下略
}
$rmask2 = $rmask1;
}
rse...@midicity.co.jp (SEKIDO Ryoichi) writes:
>Perl の select システムコールでよく分からないことがあるので,お尋ねします
>.
>クライアントからの接続を select で待ち受けて処理しようとしていますが,
>新しい接続を accept で受けても,帰ってくるファイルハンドルが1回目と同じに
>
>なってしまいます.そうではなくて,クライアント間のやりとりを仲立ちするよう
>な
>プログラムを作りたいのです.
ファイルハンドルに毎回おなじシンボル使っているからです。
perlfaq5にこのあたりの記述があります。
How do I make an array of filehandles? あたりでサーチしてみてください。
古来から伝わる方法としては、最初に
$seq = 0;
として、acceptのあたりを、
local $NS = `C` . ++seq;# `C`は単にユニークな文字列ってだけで、なんでもよい。
accept($NS, S); # つまり、`C0`、`C1`、`C2` ...と云うシンボルが渡る
:
vec($rmask1, fileno($NS), 1) = 1;
:
とすると云うのがあります。毎回違う識別子を与えるのですね。
と、perlfaq5を見たら、perl5的には、同じことを、
use Symbol;
:
my $NS = gensym();
:
とするのですね。
あと、ついでですが、IPCに関する部分は、perl5ではもう少しきれいな書き方
ができますよ。perlipcをみてみたらどうでしょうか。
# それももう古いか……今はIO::Socketかな
では
はは
--
Hideyuki Endo end...@remus.dti.ne.jp