免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2303 | 回复: 2
打印 上一主题 下一主题

socket的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-08-27 15:49 |只看该作者 |倒序浏览
只是一个简单的命令传输器,可以执行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

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 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 占用率变大的唯一原因。

论坛徽章:
0
3 [报告]
发表于 2008-08-27 16:19 |只看该作者
感谢版大
好歹明白了
本来的意思是想服务器发起一个主动关闭
应该是  $cl->close();
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP