IO::Socket::Async
提供异步套接字,适用于服务器和客户端。
下面是一个简单的“hello world”HTTP 服务器示例,该服务器监听端口 3333
react
以及一个连接到它的客户端,并打印出服务器的回答
await IO::Socket::Async.connect('127.0.0.1', 3333).then( ->);
IO::Socket::Async
还可以发送和接收 UDP 消息。输出其接收的所有数据的示例服务器如下
my = IO::Socket::Async.bind-udp('localhost', 3333);react
关联的客户端可能是
my = IO::Socket::Async.udp();await .print-to('localhost', 3333, "Hello, Raku!");
可以包含 CATCH
phaser,以专门处理此类套接字中可能发生的错误,例如端口已被占用
react# Will print this, if address 3000 is already in use:# X::AdHoc→ address already in use# handled in 23
与使用其他 phaser(例如 CATCH
)的主要区别在于,此类异常将在 whenever
块中捕获,并将使程序退出(或不退出)受您的控制。
方法§
IO::Socket::Async
无法直接构造,应使用 connect
或 listen
(用于 TCP 连接)或 udp
或 bind-udp
(用于 UDP 数据)来分别创建客户端或服务器。
方法 connect§
method connect(Str , Int --> Promise)
尝试连接到 $host
和 $port
指定的 TCP 服务器,返回一个 Promise
,该 Promise
将保留已连接的 IO::Socket::Async
,或者在无法建立连接时中断。
方法 connect-path§
method connect-path(Str --> Promise)
尝试连接到 $path
指定的 Unix 域流套接字,返回一个 Promise
,该 Promise
将保留已连接的 IO::Socket::Async
,或者在无法建立连接时中断。
方法 listen§
method listen(Str , Int --> Supply)
在指定的 $host
和 $port
上创建一个侦听套接字,返回一个 Supply
,已接受的客户端 IO::Socket::Async
将被发送到该 Supply
。应点按此 Supply
以开始侦听客户端连接。如果您希望操作系统为您查找端口,则可以将 $port
设置为 0
。
通过对返回的 Supply
调用 tap 方法返回的 IO::Socket::Async::ListenSocket
表示底层侦听 TCP 套接字,可以使用其 close 方法关闭该套接字。如果 $port
设置为 0
,则可以使用其 socket-port 方法获取套接字最终使用的端口。
方法 listen-path§
method listen-path(Str )
在指定的 $path
上创建一个 Unix 域流监听套接字,返回一个 Supply
,其中将发出已接受的客户端 IO::Socket::Async
。此 Supply
应被轻触以开始监听客户端连接。
通过调用供应上返回的 tap 方法返回的 IO::Socket::Async::ListenSocket
表示底层监听 TCP 套接字,可以使用其 close 方法关闭该套接字。
方法 udp§
method udp(IO::Socket::Async: : --> IO::Socket::Async)
返回一个已初始化的 IO::Socket::Async
客户端对象,该对象已配置为使用 print-to
或 write-to
发送 UDP 消息。:broadcast
副词将设置 SO_BROADCAST
选项,该选项将允许套接字向广播地址发送数据包。
方法 bind-udp§
method bind-udp(IO::Socket::Async: Str() , Int() , : --> IO::Socket::Async)
这将返回一个已初始化的 IO::Socket::Async
服务器对象,该对象已配置为接收发送到指定的 $host
和 $port
的 UDP 消息,并且等效于 TCP 套接字的 listen
。可以指定 :broadcast
副词以允许接收发送到广播地址的消息。
方法 print§
method print(IO::Socket::Async: Str --> Promise)
尝试在 IO::Socket::Async
上发送 $str
,该 IO::Socket::Async
将通过 connect
或 listen
间接获取,返回一个 Promise
,该 Promise
将保留发送的字节数或在发送时出错时中断。
方法 print-to§
method print-to(IO::Socket::Async: Str() , Int() , Str() --> Promise)
这等效于使用 udp
方法创建的 UDP 套接字的 print
,它将尝试向指定的 $host
和 $port
发送 $str
的 UDP 消息,返回一个 Promise
,该 Promise
将在成功发送数据时保留,或在无法发送数据时中断。为了发送到广播地址,必须在创建套接字时指定 :broadcast
标志。
方法 write§
method write(IO::Socket::Async: Blob --> Promise)
此方法将尝试在 IO::Socket::Async
上发送 $b
中的字节,该 IO::Socket::Async
将通过 connect
或 listen
间接获取,返回一个 Promise
,该 Promise
将保留发送的字节数或在发送时出错时中断。
方法 write-to§
method write-to(IO::Socket::Async: Str() , Int() , Blob --> Promise)
这等效于使用 udp
方法创建的 UDP 套接字的 write
。它将尝试向指定的 $host
和 $port
发送由 Blob
$b
中的字节组成的 UDP 消息,返回一个 Promise
,该 Promise
将在成功发送数据时保留,或在无法发送数据时中断。为了发送到广播地址,必须在创建套接字时指定 :broadcast
标志。
方法 Supply§
method Supply(:, : = buf8.new --> Supply)
返回一个 Supply
,可以点击它来获取从连接的 IO::Socket::Async
中读取的数据。默认情况下,数据将以字符形式发出,但如果提供了 :bin
副词,则会发出一个字节的 Buf
,在这种情况下,您可以使用 :buf
命名参数提供自己的 Buf
。
字符模式下的 UDP 套接字将每个数据包视为一个完整的消息并对其进行解码。如果发生解码错误,则 Supply
将 quit
。
另一方面,TCP 套接字将传入的数据包视为流的一部分,并将传入的字节馈入流式解码器。然后它会发出解码器认为已准备好的任何字符。由于字符串在 Raku 中以音素级别工作,这意味着只会发出已知的完整音素。例如,如果使用 UTF-8 编码并且数据包中的最后一个字节解码为 a
,则不会发出此字节,因为下一个数据包可能包含一个组合字符,该字符应与 a
形成一个音素。控制字符(例如 \n
)始终作为音素边界,因此任何使用换行符或空字节作为终止符的基于文本的协议都不需要特殊考虑。TCP 套接字在解码错误时也会 quit
。
方法 close§
method close(IO::Socket::Async: )
关闭连接的客户端 IO::Socket::Async
,该客户端将从 listen
Supply
或 connect
Promise
中获取。
为了关闭 listen
创建的底层侦听套接字,您可以 close
IO::Socket::Async::ListenSocket
。有关示例,请参见 listen。
方法 socket-host§
method socket-host(--> Str)
返回此套接字本地端的 IP 地址。
方法 peer-host§
method peer-host(--> Str)
返回此套接字远程端的 IP 地址。
方法 socket-port§
method socket-port(--> Int)
返回此套接字本地端的端口。
方法 peer-port§
method peer-port(--> Int)
返回此套接字远程端的端口。
方法 native-descriptor§
method native-descriptor(--> Int)
返回此套接字的文件描述符。