• ベストアンサー

IO::Socketでacceptを実行すると待機状態になる

IO::Socketを使って、accept();を実行すると接続があるまでずっと待機状態になってしまいます。 調べたところ、これはaccept()の仕様だという事は分かったのですが、これをなんとかして一定時間たったらあきらめる。という風には出来ないのでしょうか?

  • Perl
  • 回答数3
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

alarmとevalによる方法 eval { local $SIG{ALRM} = sub { die "alarm!!\n" }; alarm 10; #10秒 eval { #時間のかかる処理 }; alarm 0; #取り消し }; alarm 0; die if $@ && $@ !~ /alarm!!/; #上記のメッセージの捕捉 #クックブックに載ってた方法です。

Justic
質問者

お礼

alarmとevalではそのように処理をするのですか。 もう既に別の方法で問題は解決してしまいましたが、 今後のプログラミングの参考にさせていただきます。 BLUEPIXYさん、親切な回答ありがとうございました。

その他の回答 (2)

  • omni2
  • ベストアンサー率53% (33/62)
回答No.2

よくわかりませんが、 $sock->accept(); の前に $sock->timeout(10);とか書けばよいのかもしれません・・ まちがってたらごめんなさい。。

Justic
質問者

お礼

omni2さん、osamuyさん、すばやい返事ありがとうございます。 2人が書いた内容で試してみようと思い、検索しなおしたところ意外な答えが見つかりました。 (単に自分の検索ワードがいけなかったみたいです。) $client_socket = new IO::Socket::INET ( PeerAddr => 'localhost', PeerPort => '80', Proto => 'tcp', TimeOut => '5'); この1番したの行のtimeout属性でaccept();の待機時間を決めれるそうです。 足らない質問に、ご迷惑をおかけいたしました。

  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.1

selectを使ってタイムアウトさせるのが、王道と思われるので、IO::Selectを使ってみては。 Windowsだと、alarmとevalでタイムアウトさせる方が良いかもしれない。

参考URL:
http://www.perl.com/doc/manual/html/lib/IO/Select.html

関連するQ&A

  • Socket プログラミングについて

    先日の質問ではありがとうございました。 今回はソースコードについてですが もしよろしければアドバイスお願いします。 Socket 制御を行うアプリを作成しています。 ・クライアントアプリ ・サーバアプリ の2つから構成していまして同PC上で動作させます。 クライアントから localhost 経由でサーバアプリに接続。 サーバアプリは ServerSocket を生成して accept しています。 サーバアプリで accept により Socket を生成すると その Socket を Thread に引き渡して適宜処理を行います。 その後、 再び別クライアントからの接続を待つために サーバアプリで accept したいのですが そのまま accept を呼び出しても そこで待機せずに新しい Socket を生成しています。 別クライアントからの接続を待機するにはどうしたらいいのでしょうか? ご教授お願いします。

    • ベストアンサー
    • Java
  • c言語のaccept関数が待機を行いません

    c言語のaccept関数が待機を行いません 現在C言語によるプログラミングを勉強中で、 「Windows ゲームプログラミング」という書籍を教材に ネットワーク通信のプログラミングを行っております。 ネットワーク通信のプログラミングは初めてで 現在一つの壁にぶつかっております。 どうか護教授をお願い致します。 下記のサーバー側のコードですが、 (1)ソケットを作成して、bind関数でアドレスと関連付ける (2)listen関数で接続を準備する (3)accept関数でクライアントが接続するまで待機する (4)while文の中でクライアントからのメッセージを受け取る という目的で作成いたしましたが、クライアントからの接続はしていないはずなんですが、 どうもaccept関数で待機を行わず、while文に進んでしまい、無限ループに突入してしまいます。 accept関数の戻り値を確認すると「INVALID_SOCKET」でした。 現在はこのサーバーに接続するシステムは作成していないので接続はないと思います。 ポート番号などを変更してもダメでした。 お恥ずかしい質問かもしれませんが、どうかよろしくお願い致します。 以下コード WSADATA wsaData; sturuct sockaddr_in hostAddr,clAddr; SOCKET s,client; char buffer[1024]; int length; if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0) return; (1) s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); hostAddr.sin_family=AF_INET; hostAddr.sin_port=ポート番号; hostAddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1"); bind(s,&hostAddr,sizeof(struct sockaddr_in)); (2) listen(s,1); printf("クライアントからの接続を待機...\n"); (3) client=accept(s,&clAddr,&length); printf("クライアントからの接続を確認\n受信を待機...\n"); (4) while(1){ length=recv(client,buffer,1024,0); buffer[length]=0; printf("文字列を受信:%s\n",buffer); if(strcmp(buffer,"exit")==0) break; } shutdown(client,SD_BOTH); closesocket(client); closesocket(s); WSACleanup(); return 0;

  • IO-Socketで…

    最初に開かれた1つのソケットで、 サーバーから不定期に送られてくるデータを処理→表示しつつ、 ユーザーから入力があった場合にそのソケットへ送信するといったメッセンジャーを作ろうと思っているのですが、「入力待ちと受信待ちを同時に進める」という事がどうも上手くいってくれません… use threads;を使い、送信用・受信用と分けたのですが、やはりどちらか一方が止まってしまいます…。 どの様に書いたらよいのでしょうか… 何方かご教授下さい…。 use threads; use IO::Socket; ($test_socketを生成) sub send{ while($input = <STDIN>){ chomp($input); print $test_socket "$input"; } sub recv{ while(1){ if($receive = <$test_socket>){ print "$receive\n"; } } } my $sendthread = threads->new(\&send); $sendthread->join(); my $recvthread = threads->new(\&recv); $recvthread->join();

  • Perl / IO::Socketによる送受信について

    IO::Socketを利用してクライアントを作成しようとしているのですが、サーバーが返すパケットの末尾が 0A(\n) ではなく 00(←?) であるため、クライアント側で while ($receive = <$client_socket>) { print $receive; } を使用し正常に受信・表示する事が出来ないようです。末尾が 00 で終わっているデータを受信・表示するにはどうしたら良いのでしょうか?

  • Linuxのsocket接続でacceptできない

    Ubuntu 10.10 + gcc4.4 + eclipse で C言語プログラミングをしています。 ソケットを使用したプログラムを試していたのですが、思うように動作しません。 作成したプログラムは以下のようなものです。 ・ローカルマシン上で、サーバプログラム、クライアントプログラムを用意する ・サーバ側はソケット作成後、クライアントが接続するまで listen する ・クライアントはサーバに接続したら、接続した旨を表示する という初歩的なものです。 問題は、サーバ側が accept したときに戻り値 -1 を返却して終了してしまうことです。 以下が作成したソースです。 ■■■▼ サーバ側ここから ▼■■■ #include <sys/socket.h> #include <sys/un.h> #include <stdlib.h> #include <stdio.h> int main(int argc, char *argv[]) { int sockfd; struct sockaddr_un srv; socklen_t socklen; /* ソケット名をコマンド入力で受け取る */ if(argc != 2) { puts("USAGE: mksock <filename>"); exit(EXIT_FAILURE); } /* ソケット作成 */ if((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0){ exit(EXIT_FAILURE); } /* srv 初期化 */ memset(&srv, 0, sizeof(srv)); srv.sun_family = AF_UNIX; strncpy(srv.sun_path, argv[1], sizeof(srv.sun_path)); /* バインド */ if((bind(sockfd, (struct sockaddr *)&srv, SUN_LEN(&srv))) < 0){ exit(EXIT_FAILURE); } /* クライアントからの接続待ち */ if((listen(sockfd, 5)) < 0) { exit(EXIT_FAILURE); } printf("socket available: %s, sockfd=%d\n", srv.sun_path, sockfd); /* 接続がある限りくりかえす */ int sockResult; while(1) { sockResult = accept(sockfd, (struct sockaddr *)&srv, &socklen); printf("sockResult = %d, sun_path=%s\n", sockResult, srv.sun_path); if (sockResult < 0) break; puts("new connection granted"); } puts("mksock end"); exit(EXIT_SUCCESS); } ■■■▲ サーバ側ここまで ▲■■■ ●●●▼ クライアント側ここから ▼●●● #include <sys/socket.h> #include <sys/un.h> #include <stdlib.h> #include <stdio.h> int main(int argc, char *argv[]) { int sockfd; struct sockaddr_un cli; socklen_t socklen; /* ソケット名をコマンド入力で受け取る */ if(argc != 2) { puts("USAGE: sockconn <filename>"); exit(EXIT_FAILURE); } /* ソケット作成 */ if((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0){ exit(EXIT_FAILURE); } /* クライアント設定 */ memset(&cli, 0, sizeof(cli)); cli.sun_family = AF_UNIX; strncpy(cli.sun_path, argv[1], sizeof(cli.sun_path)); /* サーバへ接続 */ socklen = SUN_LEN(&cli); if(connect(sockfd, (struct sockaddr *)&cli, socklen)) { exit(EXIT_FAILURE); } printf("connected to socket %s\n", cli.sun_path); exit(EXIT_SUCCESS); } ●●●▲ クライアント側ここまで ▲●●● これから作成されたバイナリを同一フォルダに置いて、作成ユーザで、カレントディレクトリで実行しました。 以下が実行時の入出力です(カッコ内は実行順序)。 ■▼ サーバ側ここから ▼■ $ ./mksock jjj1…(1) $ socket available: jjj1, sockfd=3 $ sockResult = -1, sun_path=jjj1 $ mksock end ■▲ サーバ側ここから ▲■ ●▼ クライアント側ここから ▼● $ ./sockconn jjj1…(2) $ connected to socket jjj1 ●▲ クライアント側ここから ▲● 上記のように、サーバ側が accept 時に -1 を返却しています。 パーミッションについては以下になっています。 srwxr-xr-x 1 hoge hoge 0 2011-09-04 21:36 jjj1 -rwxr--r-- 1 hoge hoge 86870 2011-09-04 21:36 mksock -rwxr--r-- 1 hoge hoge 86775 2011-09-04 21:36 sockconn パーミッションを見る限り、ソケットファイルにはアクセスできているかと。 おそらく環境周りではないかと思いますが、考えつきません。 linux プログラミングに詳しいかた、よろしくお願いいたします。

  • socketについて

    こんにちわ ソケットプログラムで質問なのですが ソケット作成(listen状態)後selectで通信を待っています。 その後selectを抜けて(通信がきたはず?)その直後にあるacceptでプログラムがとまってしまいます。 selectでは上記で作成したソケットしか感知しないようになっています。 これはselectを抜けてacceptにいくまでに通信が切れてしまったのでしょうか? socket~bind~listen~select~accept               ↑このタイミングで通信が切れたのでしょうか?

  • socket.ioでCSSが効かない問題について

    現在サクラVPS上でnpm+node+socket.ioで簡易なwebアプリを作成しようとしています。 コンソールを叩きサーバーサイドのapp.jsを起動し、ポート8080でアクセスした際、 接続には一応成功しているようなのですが、ブラウザ上でCSSが効いてくれません。 通常のポート番号80では問題ありません。 googleの検索にもかからず途方にくれています。 恐らく酷く初歩的なミスかと思うのですがお教え頂けると幸いです。

  • 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
  • ブラウザ上からなら実行可能なスクリプトがコマンドラインだと実行しません

    ブラウザ上からなら実行可能なスクリプトがコマンドラインだと実行しません windowXP, perl5 で開発しています。 簡単なプログラム(test.pl)なのですが ----- #!/usr/bin/perl use IO:Socket メール送信処理 1; ----- ブラウザ上から実行すると正しくメール送信されますが、 これをコマンドプロンプトから ----- perl test.pl ----- とすると、 Can't locate IO/Socket.pm と出てしまいます。 pathが通ってないとか絶対パスとかそのあたりかと思い、 socket.pmのあるパスを通したりしましたが、変化しません。 use IO::Socket を絶対パスとかで指定するのでしょうか? 解決方法をお教え頂ければと思います。 よろしくお願い致します。

    • ベストアンサー
    • Perl
  • PerlでIO::Socket::INET: connect: Unknown errorについて プロキシ設定?

    PerlでIO::Socket::INET: connect: Unknown errorが発生します。IEを使う時でもインターネットに接続する場合、プロパティで192.168.1.1を設定しておりますが、 プロシキ接続できる、設定方法はあるのでしょうか?

    • ベストアンサー
    • Perl

専門家に質問してみよう