加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Perl中的基本网络聊天应用程序

发布时间:2020-12-15 23:36:07 所属栏目:大数据 来源:网络整理
导读:我正在尝试在Perl中编写一个基本的网络聊天应用程序用于学习目的.我目前有一个服务器和客户端程序,几乎按照我的要求运行.多个客户端可以连接到服务器并向其发送消息.但是,我不确定如何将消息从一个客户端发送到另一个客户端,并希望在这里推进正确的方向.这是
我正在尝试在Perl中编写一个基本的网络聊天应用程序用于学习目的.我目前有一个服务器和客户端程序,几乎按照我的要求运行.多个客户端可以连接到服务器并向其发送消息.但是,我不确定如何将消息从一个客户端发送到另一个客户端,并希望在这里推进正确的方向.这是我到目前为止的代码,想法?

注意:这是我第一次尝试使用网络或使用Perl进行正确的项目,因此任何其他关于如何编写它的指导也将受到赞赏.

chat_server.pl

#!/usr/bin/perl -w
# chat_server.pl
use strict;
use IO::Socket::INET;

my $port = shift or die "Port required!n";
my $socket = IO::Socket::INET->new(
        LocalPort   => $port,Proto       => 'tcp',Listen      => SOMAXCONN
    ) or die "Can't create socket: $!!n";
my $child;

print "Listening for clients on $port...n";
REQUEST:
while(my $client = $socket->accept) {
    my $addr = gethostbyaddr($client->peeraddr,AF_INET);
    my $port = $client->peerport;

    if($child = fork) {
        print "New connection from $addr:$portn";
        close $client;
        next REQUEST;
    } die "fork failed!n" unless defined $child;

    while (<$client>) {
        print "[$addr:$port] says: $_";
        print $client "[$addr:$port] says: $_";
    }   
}
close $socket;

chat_client.pl

#!/usr/bin/perl -w
# chat_client.pl
use strict;
use IO::Socket::INET;

my $port            = shift or die "No portn";
my $server          = shift or die "No servern";
my $client_socket   = IO::Socket::INET->new(
        PeerPort    =>  $port,PeerAddr    =>  $server,Proto       =>  'tcp'
    ) or die "Can't create send socket: $!!n";

my $child;

if($child = fork) {
    while(1) {
        sleep(1);
        print scalar <$client_socket>;
    }
}

die "fork failed!n" unless defined $child;
print "Connected to $server:$port!n";

do {
    print "> ";
    print $client_socket $_ if defined $_;
} while(<STDIN>);

print "Closing connection";
close $client_socket;

解决方法

单个客户端到单个服务器并不太困难 – 您正在使用的代码 – 有效地 – 创建1对1关系.您的分叉服务器专门与您的客户交谈.

要获取在多个客户端之间传播(通过服务器)的信息,您将不得不变得更复杂 – 因为您有单独的进程,这些进程现在需要相互通信.这是一个足够大的问题,有关于它的perl文档的整个部分:perlipc.

这实际上会大大增加代码的复杂性,因为您正在转移到通信上的1对多关系,并且它们都将异步发生.

基于套接字的通信是进程间通信(IPC)的一种形式,您已经在这样做了.但是你的’问题’在于你从1到1的通信转移到1到多个通信.你需要能够进行广播,而这种通信方式并不能很好地支持.

我建议看看IO::Pipe – 我在这里有一些示例代码:How to extract data from Parallel::ForkManager in perl

然后使用IO::Select和can_read异步判断管道上是否有任何数据.您可能需要一个管道数组 – 每个客户端一个 – 否则您可能会遇到重复的并发内容.

例如.:

(来自IO :: Pipe doc页面:

my $pipe = IO::Pipe->new();
if($pid = fork()) { # Parent
        $pipe->reader();
        while(<$pipe>) {
        ...
        }
    }
    elsif(defined $pid) { # Child
        $pipe->writer();
        print $pipe ...
    }

不幸的是,这里有一个小问题 – 您的管道将由分叉过程创建,但这反过来意味着您需要弄清楚如何处理管道数组并检查它们是否可读.

这意味着你不能再坐在接受套接字的while循环中了 – 那些阻塞,所以你有消息排队,直到另一个客户端连接(这实际上不是你想要的).所以你还需要再次使用select来检查是否有东西可以先接受.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读