Chinaunix

标题: socket的问题 [打印本页]

作者: redicaps    时间: 2008-08-27 15:49
标题: socket的问题
只是一个简单的命令传输器,可以执行server的一些命令而已。
现在问题是第一次连接能够成功,执行都没有问题。但退出之后就不能够再次连接,出现connection refused的错误
而且server进程占cup开始彪升
看了半天解决不了了,高手帮忙看看
下面是主程序的主逻辑部分。
附件有所有代码

  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use watch;
  5. use IO::Socket;
  6. use IO::File;
  7. use Log::Tiny;
  8. use Fcntl;
  9. use POSIX qw/WNOHANG setsid/;
  10. use constant LOCALHOST => 127.0.0.1;
  11. use constant PORT      => 2007;
  12. use constant PIDFILE   => '/var/tmp/watch.pid';
  13. use constant USER      => 'nobody';
  14. use constant GROUP     => 'nogroup';

  15. my ( $pid, $log, $server ) = ( 0, 0, 0 )
  16.   ;    #给pid赋值,防止出现在父进程结束时有pid无初值的错误
  17. my %commands = (
  18.     q    => sub { undef },
  19.     ps   => sub { $server->ps(); },
  20.     w    => sub { $server->w(); },
  21.     dt   => sub { $server->show(); },
  22.     free => sub { $server->free(); }
  23. );

  24. my $port    = PORT;
  25. my $pidfile = PIDFILE;
  26. my $quit    = 0;
  27. $pid = initserver( PIDFILE, USER, GROUP );
  28. $server = new watch(
  29.     Listen    => 20,
  30.     LocalPort => $port,
  31.     Reuse     => 1,
  32.     Timeout   => 60 * 60
  33. );
  34. die "Can not socket:$@\n" unless $server;
  35. $log->INFO("Listening on port:$port\n");

  36. my $sock = $server->getSock;
  37. $SIG{'INT'} = $SIG{'TERM'} = sub { $quit++ };
  38. while ( !$quit ) {
  39.     next unless my $cl = $sock->accept;
  40.     my $peerhost = $cl->peerhost;
  41.     my $peerport = $cl->peerport;
  42.     my $client   = " [$peerhost:$peerport] ";
  43.     $log->INFO("connection from $client established\n");
  44.     while (<$cl>) {
  45.         chomp;
  46.         $_ =~ /^q$/i and last;
  47.         if ( exists( $commands{$_} ) ) {
  48.             my $sub = $commands{$_};
  49.             $log->INFO("client $client sends command: $_\n");
  50.             my @c = $sub->();
  51.             foreach (@c) {
  52.                 print $cl $_ . "\n";
  53.             }
  54.         }
  55.         else {
  56.             $log->WARN("unknow command: $_ from client $client!\n");
  57.             print $cl "unknow command\n";
  58.         }
  59.     }
  60.     print $cl "bye\n";
  61.     $server->sockclose();
  62. }


复制代码

watch.tar

10 KB, 下载次数: 25


作者: flw    时间: 2008-08-27 15:56
在回答你的问题之前先说一点:
本着解决问题完成工作任务的态度,
POE 有一个 job server,基本能够满足你的需求,你可以参考一下:
http://poe.perl.org/?POE_Cookbook/Job_Server

接下来说说你程序中的问题,
你的程序在服务完一个客户端请求之后,执行了 $server->sockclose(),关闭了服务端监听的 socket,
这就是你的服务器在连接了一次之后就再也无法提供服务的唯一原因;
关闭了监听 socket 之后,导致 $server->accept 总是失败,因此程序在这两行之间不停地循环:
while ( !$quit ) {
    next unless my $cl = $sock->accept;
这就是你的 CPU 占用率变大的唯一原因。
作者: redicaps    时间: 2008-08-27 16:19
感谢版大
好歹明白了
本来的意思是想服务器发起一个主动关闭
应该是  $cl->close();




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2