Raku UDP 服务器如何知道将响应发送到哪里?

jja*_*jja 8 sockets udp raku

我可以编写一个 UDP 服务器,它将使用 IO::Socket::Async 从客户端接收消息

my $socket = IO::Socket::Async.bind-udp: 'localhost', 3333;

react whenever $socket.Supply: :bin {
    say "Received some junk: { .gist }";    
}
Run Code Online (Sandbox Code Playgroud)

我可以将东西发送到该服务器:

given IO::Socket::Async.udp {
    await .print-to: 'localhost', 3333, 'Hello';
}
Run Code Online (Sandbox Code Playgroud)

但是当我尝试让服务器发回消息响应时,我意识到我没有要发送消息的主机和端口。我怎样才能得到这些信息?

通常,我认为这个问题的答案是使用recvfrom并传递一个指向sockaddr结构的指针,该结构将填充传入连接的地址信息。但如果不使用 NativeCall 似乎就没有办法做到这一点(即使如此,我也不清楚如何做到这一点)。

或者我错过了什么?

rai*_*iph 8

TL;DR您的问题的解决方案是由 timo++ 实现的,以回应与您类似的 SO 问题,然后由 Kaiepi 在他们接受的答案中很好地记录。请相应地访问并投票。我在这里写的其余内容可以说是多余的。


官方文档没有提到解决方案(将:datagram参数传递给IO::Socket::Async.Supply方法)并使用您从供应中获得的Datagrams 。

以下是在两端使用低电平电源抽头的示例:

# Server

given IO::Socket::Async .bind-udp('localhost', 3333) {
  .Supply(:datagram)
    .tap: {
      say "Received client data: { .data.gist }";
      IO::Socket::Async.udp.print-to: .hostname, .port, 'Loud and clear!';
    }
}

# Client

given IO::Socket::Async.udp {
  .print-to: 'localhost', 3333, 'Can you hear me?';
  .Supply
    .tap: {
      say "Received server data: { .gist }";
      IO::Socket::Async.udp.print-to: 'localhost', 3333, 'Great :)';
    }
}

sleep 1;
Run Code Online (Sandbox Code Playgroud)

显示:

Received client data: Can you hear me?
Received server data: Hi!
Received client data: Great :)
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!这非常有用。令我惊讶的是,这个合并已经花费了 5 年时间,但仍未记录在案。这只是缺少 TUIT 吗?或者其中的某些部分仍然是草案?另外:是否有理由创建一个新的套接字来写入客户端,而不仅仅是“$socket.print-to”?我注意到,按照您的方式,客户端会从与其连接的端口不同的端口获得响应,这似乎是意外的,但也许有一个很好的理由这样做? (2认同)
  • 哈!没问题。我没有看到其他问题,所以我很高兴您花时间提供帮助。我很高兴知道这样做没有什么特殊的理由:这样可以将货物崇拜降到最低限度 (2认同)