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

套接字 – Perl 6 udp套接字:如何从服务器读取响应?

发布时间:2020-12-16 06:24:37 所属栏目:大数据 来源:网络整理
导读:server-udp.pl my $socket = IO::Socket::Async.bind-udp('localhost',3333);react { whenever $socket.Supply - $v { if $v.chars 0 { $v.print; } }} client-udp.pl my $socket = IO::Socket::Async.udp();await $socket.print-to('localhost',3333,"nHel
server-udp.pl

my $socket = IO::Socket::Async.bind-udp('localhost',3333);
react {
    whenever $socket.Supply -> $v {
        if $v.chars > 0 {
            $v.print;
        }
    }
}

client-udp.pl

my $socket = IO::Socket::Async.udp();
await $socket.print-to('localhost',3333,"nHello,Perl 6!");

客户端如何读取服务器响应?
也许这还没有实现?

例如在Perl 5中:

client.pl

...
my $data_send = "Test 1234567890";
$client_socket->send( $data_send )
    or die "Client error while sending: $!n";

# read operation
$client_socket->recv( my $data_rcv,1024 )
    or die "Client error while received: $!n";

print "Received data: $data_rcvn";
...

解决方法

首先让我重申我上面的评论.从阅读 IO::Socket::Async的文档,我没有看到一个明显的方法来做到这一点.您既可以设置UDP发送方,也可以设置UDP接收方,但不能同时设置两者.

UDP连接由4个东西定义,(发送方地址,发送方端口,接收方地址,接收方端口).

服务器可以侦听给定的地址/端口.收到数据包后,通常会有方法查询发件人的地址/端口.这就是我在Perl 6中看不到的东西.

客户端可以将数据包定向到特定的服务器地址/端口.客户端通常会选择一个随机的“发送端口”,给出“连接”所需的第四个元素(在这种无连接协议中).

因此,如在其他语言的示例中,客户端发送数据包,服务器查找发送方的地址/端口,然后将数据包返回到同一地址/端口.在发送其数据包之后,客户端再次侦听它发送数据包的相同随机端口,以接收来自服务器的响应.我没有在Perl 6中看到一个明显的方法,就是在刚刚发送到的同一端口上使用recv跟进打印到.

话虽如此,Perl 6有一个出色的NativeCall工具,可用于直接调用动态库,因此如果您愿意,可以通过实际系统调用完成所需的一切.

无论如何,这不是’官方’Perl 6方式,一旦IO :: Socket :: Async可以做你想做的事,就可以从脑中清除所有这些,但是这里是如何用NativeCall做的:

server-udp.pl

use NativeCall;

constant AF_INET := 2;
constant SOCK_DGRAM := 2;

class sockaddr_in is repr('CStruct')
{
    has int16 $.sin_family;
    has uint16 $.sin_port;
    has int32 $.sin_addr;
    has int64 $.pad;
}

sub socket(int32,int32,int32 --> int32) is native() {}
sub bind(int32,sockaddr_in,uint32 --> int32) is native() {}
sub htons(uint16 --> uint16) is native() {}
sub ntohs(uint16 --> uint16) is native() {}
sub inet_ntoa(int32 --> Str) is native() {}
sub perror(Str) is native() {}
sub recvfrom(int32,Blob,size_t,int32 is rw --> ssize_t) is native() {}
sub sendto(int32,int32 --> ssize_t) is native() {}

my int32 $sock = socket(AF_INET,SOCK_DGRAM,0);
perror('socket') // die if $sock < 0;

my $addr = sockaddr_in.new(sin_family => AF_INET,sin_port => htons(3333),sin_addr => 0);

my $ret = bind($sock,$addr,nativesizeof(sockaddr_in));

perror('bind') // die if $ret < 0;

my $buf = buf8.allocate(1024);

my $fromaddr = sockaddr_in.new;

my int32 $addrsize = nativesizeof(sockaddr_in);

loop
{
    $ret = recvfrom($sock,$buf,$buf.bytes,$fromaddr,$addrsize);
    perror('recvfrom') // die if $ret < 0;

    my $msg = $buf.decode;
    $msg.print;

    my $return-msg = "Thank you for saying $msg";
    my $return-buf = $return-msg.encode;

    $ret = sendto($sock,$return-buf,$return-buf.bytes,$addrsize);
    perror('sendto') // die if $ret < 0;
}

client-udp.pl

use NativeCall;

constant AF_INET := 2;
constant SOCK_DGRAM := 2;

class sockaddr_in is repr('CStruct')
{
    has int16 $.sin_family;
    has uint16 $.sin_port;
    has int32 $.sin_addr;
    has int64 $.pad;
}

sub socket(int32,int32 --> int32) is native() {}
sub htons(uint16 --> uint16) is native() {}
sub inet_ntoa(int32 --> Str) is native() {}
sub inet_aton(Str,int32 is rw --> int32) is native() {}
sub perror(Str) is native() {}
sub recvfrom(int32,int32 is rw --> ssize_t) is native() {}
sub recv(int32,int32 --> ssize_t) is native() {}
sub sendto(int32,0);
perror('socket') // die if $sock < 0;

my int32 $addr-ip;
inet_aton('127.0.0.1',$addr-ip) or die "Bad address";

my $addr = sockaddr_in.new(sin_family => AF_INET,sin_addr => $addr-ip);

my $msg = "Hello,Perl 6!n".encode;

my $ret = sendto($sock,$msg,$msg.bytes,nativesizeof(sockaddr_in));
perror('sendto') // die if $ret < 0;

my $buf = buf8.allocate(1024);

$ret = recv($sock,0);

say "Return Msg: ",$buf.decode;

(编辑:李大同)

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

    推荐文章
      热点阅读