套接字 – Perl 6 udp套接字:如何从服务器读取响应?
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; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |