免费注册 查看新帖 |

Chinaunix

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

IO::Socket Server Client 数据交互 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-02-23 12:10 |只看该作者 |倒序浏览
刚开始看perl 请多指教。我是看了网上的一个多进程代码http://beatasatan.blog.sohu.com/55313188.html自己想做点改进

目标:
Server 会发送一些列命令给client,client收到后回复server。
收到命令'EXIT',client 断开连接。

问题:
1.server 和 client端如何实现数据交互?sysread 和syssend?


客户端代码
# tcp_iosocket_cli.pl
use strict;
use IO::Socket;

my $addr = $ARGV[0] || '127.0.0.1';
my $port = $ARGV[1] || '3000';
my $buf = undef;

my $sock = IO::Socket::INET->new(
        PeerAddr => $addr,
        PeerPort => $port,
        Proto    => 'tcp')
    or die "Can't connect: $!\n";
while(1){
    $buf = <$sock>;
    chomp($buf);
    my $bs = length($buf);
    print "Received $bs bytes, content [$buf]\n"; # actually get $bs bytes
    if($buf eq "CMD")
    {
        print "the command is CMD \n";
        发送数据如何实现?

    }
    if($buf eq "EXIT")
    {
        print "get the command EXIT\n";
        last;
    }
   
   
    sleep 5;
}
close $sock;


server 代码:

# tcp_iosocket_dt_srv.pl
use strict;
use IO::Socket;
use POSIX qw(WNOHANG);

$SIG = sub {
     while((my $pid = waitpid(-1, WNOHANG)) >0) {
          print "Reaped child $pid\n";
      }
};

my $port     = $ARGV[0] || '3000';
my $sock = IO::Socket::INET->new( Listen    => 20,
                                  LocalPort => $port,
                                  Timeout   => 60*1,
                                  Reuse     => 1)
  or die "Can't create listening socket: $!\n";

warn "Starting server on port $port...\n";
while (1) {
     next unless my $session = $sock->accept;
     defined (my $pid = fork) or die "Can't fork: $!\n";

     if($pid == 0) {
        my $peer = gethostbyaddr($session->peeraddr,AF_INET) || $session->peerhost;
        my $port = $session->peerport;
        warn "Connection from [$peer,$port]\n";
        my $ipadd=inet_ntoa($session->peeraddr);
        print "$ipadd\n";
        $session->autoflush(1);
        print $session "CMD","\n";
        while(1)
        {
            my $test;
            #此处接受数据
            sysread($sock,$test,4096);
            print $test."\n";
            print "just for test\n";
            chomp($test);
            if($test eq "ok")
            {
                 print $session "EXIT","\n";
                 last;
            }
            sleep 1;
        }
        warn "Connection from [$peer,$port] finished\n";
        close $session;
        exit 0;
      }else {
          print "Forking child $pid\n";
      }
}
close $sock;

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2009-02-23 12:29 |只看该作者
面向行的协议 print 就可以了。
syswrite/sysread 也行,不过需要自己做好控制。

如果是为了应用,而不是搞清楚原理的话,
淡淡地建议一句:用 POE。

论坛徽章:
0
3 [报告]
发表于 2009-02-24 09:22 |只看该作者
谢谢flw

面向行的协议 print 就可以了。
syswrite/sysread 也行,不过需要自己做好控制。
>>这两个是都可以 只是server那边是sysread($session,$test,1024);client端是sysread($sock,$buf,1024);。
  

如果是为了应用,而不是搞清楚原理的话,
淡淡地建议一句:用 POE。
>>我在xfocus上发现了个例子,或许有人也想看看 http://www.xfocus.net/articles/200510/826.html


新问题:

1.client端程序 如果被ctlr + c 结束 ,Server这边一般如何结束进程? 用alarm?

[ 本帖最后由 vagabondyl 于 2009-2-24 09:29 编辑 ]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
4 [报告]
发表于 2009-02-24 09:37 |只看该作者
> 1.client端程序 如果被ctlr + c 结束 ,Server这边一般如何结束进程? 用alarm?
用 POE 的话,这些都会被 POE 处理好。
如果需要额外的处理动作的话,
设定 CloseEvent 的 handler 就可以了。

[ 本帖最后由 flw 于 2009-2-24 09:38 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2009-02-24 16:36 |只看该作者
原帖由 flw 于 2009-2-24 09:37 发表
> 1.client端程序 如果被ctlr + c 结束 ,Server这边一般如何结束进程? 用alarm?
用 POE 的话,这些都会被 POE 处理好。
如果需要额外的处理动作的话,
设定 CloseEvent 的 handler 就可以了。

>>>
通过$SIG{TERM} client是可以捕获ctlr+c 的 。

$SIG{TERM}=$SIG{INT}=\& sendinfosub;
...
sub sendinfosub
{
        print "hi get it \n";
        print $_sock, "CMDOK\n";
}

只是print $_sock, "CMDOK\n"; 是始终没有发送给Server .应该是sock print之前就已经关闭了 ,所以才会出现IO::Socket::INET=GLOB(0x1908470)CMDOK
>>>
发现一个比较好的连接 关于poe的  对于像我这样的perl新手比较有用 http://poe.perl.org/?POE_Cookbook

[ 本帖最后由 vagabondyl 于 2009-2-24 16:44 编辑 ]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
6 [报告]
发表于 2009-02-24 17:58 |只看该作者
1,client 也可以用 POE。跟你说了八百遍了。
2,你不会 print。请 perldoc -f print 好好学习。

论坛徽章:
0
7 [报告]
发表于 2009-02-25 09:40 |只看该作者
原帖由 flw 于 2009-2-24 17:58 发表
1,client 也可以用 POE。跟你说了八百遍了。
2,你不会 print。请 perldoc -f print 好好学习。

不好意思 。。。 弄错了。。 是print $sock "CMDOK\n";
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP