Name
SPVM::IO::Socket - Sockets with Goroutines and Deadlines
Description
SPVM::IO::Socket is an abstract class that represents a network socket. It is designed to work seamlessly with SPVM::Go and provides powerful timeout management using absolute deadlines.
Usage
use IO::Socket::IP;
use Go;
use Go::Time;
# Create a simple TCP client
my $socket = IO::Socket::IP->new({
PeerAddr => "example.com",
PeerPort => 80,
});
# Set an absolute deadline (5 seconds from now)
my $deadline = Go::Time->now->add(Go::Duration_1l->new_from_sec(5.0));
$socket->set_deadline($deadline);
# Send a request
my $payload = "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n";
$socket->syswrite($payload);
Details
IO::Socket is an abstract class. For concrete implementations, see "Well Known Child Classes".
Socket Constant Values
See Sys::Socket::Constant for constant values such as AF_INET, SOCK_STREAM, etc.
Goroutine and Non-blocking I/O
All I/O operations in this class (connect, accept, read, write, etc.) are non-blocking and integrated with goroutines.
If an I/O operation cannot be completed immediately, the current goroutine yields control to the Go scheduler, allowing other goroutines to run. When the socket becomes ready, the goroutine is automatically resumed.
Example:
# Running a concurrent TCP server
Go->go(method : void () {
my $listen = IO::Socket::IP->new({
LocalAddr => "0.0.0.0",
LocalPort => 8080,
Listen => 10,
});
while (my $client = $listen->accept) {
# Handle each connection in a new goroutine
Go->go([$client : IO::Socket] method : void () {
my $buf = (mutable string)new_string_len 1024;
$client->sysread($buf);
$client->syswrite("Hello from Goroutine!");
$client->close;
});
}
});
Go->gosched;
Deadlines and Go::Context
This class provides three types of absolute deadlines for precise I/O control:
- 1. "Deadline" - A general deadline for all I/O operations.
- 2. "ReadDeadline" - A specific deadline for read operations (
accept,recv, etc.). - 3. "WriteDeadline" - A specific deadline for write operations (
connect,send, etc.).
Example:
# Limit only read operations to 3 seconds
my $read_limit = Go::Time->now->add(Go::Duration_1l->new_from_sec(3.0));
$socket->set_read_deadline($read_limit);
eval {
$socket->sysread($buffer);
};
if ($@ isa Go::Context::Error::DeadlineExceeded) {
# Handle the case where no data was received within 3 seconds
}
These deadlines represent absolute points in time. This mechanism is designed to be compatible with the cancellation patterns found in Go::Context, ensuring that resources are leaked neither on the server nor on the client side during long-running or stalled connections.
Well Known Child Classes
Super Class
Fields
Domain
has Domain : protected int;
A protocol family, such as AF_INET, AF_INET6, AF_UNIX.
Type
has Type : protected int;
A socket type, such as SOCK_STREAM, SOCK_DGRAM, SOCK_RAW.
Proto
has Proto : protected int;
A socket protocol, such as IPPROTO_TCP, IPPROTO_UDP.
Timeout
has Timeout : protected double;
An inactivity timeout in seconds for read, write, connect, and accept operations. This represents the maximum allowed idle time for a single I/O operation.
Listen
has Listen : protected int;
The number of listen backlog.
Sockaddr
has Sockaddr : protected Sys::Socket::Sockaddr;
A Sys::Socket::Sockaddr object used by "connect" or "bind" method.
Deadline
has Deadline : protected Go::Time;
An absolute deadline for I/O operations. If this deadline is reached, the operation is interrupted, and a Go::Context::Error::DeadlineExceeded exception is thrown.
ReadDeadline
has ReadDeadline : protected Go::Time;
An absolute deadline for read operations. This field overrides "Deadline" for read operations.
WriteDeadline
has WriteDeadline : protected Go::Time;
An absolute deadline for write operations. This field overrides "Deadline" for write operations.
Instance Methods
init
protected method init : void ($options : object[] = undef);
Options:
The following options are available adding to the options for IO::Handle#init method.
[Name][Type][Default Value]
Domain: Int = 0Type: Int = 0Proto: Int = 0Timeout: Double = 0.0Listen: Int = 0Deadline: Go::Time = undefReadDeadline: Go::Time = undefWriteDeadline: Go::Time = undef
The blocking mode of the socket is set to non-blocking mode.
Exceptions:
The Blocking option is not allowed in this class or its children.
sockdomain
method sockdomain : int ();
Returns the value of "Domain" field.
socktype
method socktype : int ();
Returns the value of "Type" field.
protocol
method protocol : int ();
Returns the value of "Proto" field.
timeout
method timeout : double ();
Returns the value of "Timeout" field.
set_timeout
method set_timeout : void ($timeout : double);
Sets "Timeout" field to $timeout. This value is used as an inactivity timeout.
deadline
method deadline : Go::Time ();
Returns the value of "Deadline" field.
set_deadline
method set_deadline : void ($deadline : Go::Time);
Sets "Deadline" field to $deadline.
read_deadline
method read_deadline : Go::Time ();
Returns the value of "ReadDeadline" field.
set_read_deadline
method set_read_deadline : void ($deadline : Go::Time);
Sets "ReadDeadline" field to $deadline.
write_deadline
method write_deadline : Go::Time ();
Returns the value of "WriteDeadline" field.
set_write_deadline
method set_write_deadline : void ($deadline : Go::Time);
Sets "WriteDeadline" field to $deadline.
set_blocking
method set_blocking : void ($blocking : int);
This method is the same as IO::Handle#set_blocking method, but if a true value is given to $blocking, an exception is thrown.
Exceptions:
Calling set_blocking method given a true value on an IO::Socket object is forbidden.
socket
protected method socket : void ();
Opens a socket using "Domain" field, "Type" field, and "Proto" field.
IO::Handle#FD field is set to the file descriptor of the socket.
This method calls Sys#socket method.
Exceptions:
Exceptions thrown by Sys#socket method could be thrown.
connect
protected method connect : void ();
Performs connect operation.
This method supports the inactivity "Timeout" and the absolute "Deadline" (or "WriteDeadline"). If a deadline is set, a monitor goroutine ensures the socket is closed at the deadline.
Exceptions:
If the absolute deadline is reached, a Go::Context::Error::DeadlineExceeded exception is thrown.
Exceptions thrown by Sys#connect method could be thrown.
Exceptions thrown by Go#gosched_io_write method could be thrown.
bind
protected method bind : void ();
Performs bind operation.
This method calls Sys#bind method given the value of IO::Handle#FD field and the value of "Sockaddr" field.
Exceptions:
Exceptions thrown by Sys#bind method could be thrown.
listen
protected method listen : void ();
Does the same thing that listen system call does given the file descriptor IO::Handle#FD field.
This method calls Sys#listen.
Exceptions:
"Listen" field must be greater than 0.
Exceptions thrown by Sys#listen method could be thrown.
accept
method accept : IO::Socket ($peer_ref : Sys::Socket::Sockaddr[] = undef);
Performs accept operation and returns a client socket object.
This method respects the inactivity "Timeout" and the absolute "Deadline" (or "ReadDeadline"). If a deadline is set, a monitor goroutine ensures the socket is closed at the deadline.
Returns a new client socket instance.
Exceptions:
If the absolute deadline is reached, a Go::Context::Error::DeadlineExceeded exception is thrown.
Exceptions thrown by Sys#accept method could be thrown.
Exceptions thrown by Go#gosched_io_read method could be thrown.
shutdown
method shutdown : void ($how : int);
Performs shutdown operation given the way $how.
This method calls Sys#shutdown method.
See Sys::Socket::Constant about constant values for $how: SHUT_RD, SHUT_WR, SHUT_RDWR.
Exceptions:
Exceptions thrown by Sys#shutdown method could be thrown.
close
method close : void ();
Closes the socket file descriptor.
Exceptions:
If this socket is not opened or already closed, an exception is thrown.
recvfrom
method recvfrom : int ($buffer : mutable string, $length : int, $flags : int, $from_ref : Sys::Socket::Sockaddr[], $offset : int = 0)
Performs recvfrom operation and returns read length.
If no data is available, it yields until the socket is ready, the inactivity timeout ("Timeout") expires, or the deadline ("Deadline" or "ReadDeadline") is reached.
Exceptions:
If the absolute deadline is reached, a Go::Context::Error::DeadlineExceeded exception is thrown.
Exceptions thrown by Sys#recvfrom method could be thrown.
Exceptions thrown by Go#gosched_io_read method could be thrown (e.g., Go::Error::IOTimeout).
sendto
method sendto : int ($buffer : string, $flags : int, $to : Sys::Socket::Sockaddr, $length : int = -1, $offset : int = 0);
Performs sendto operation and returns write length.
If the transmit buffer is full, it yields until space becomes available, the inactivity timeout ("Timeout") expires, or the deadline ("Deadline" or "WriteDeadline") is reached.
Exceptions:
If the absolute deadline is reached, a Go::Context::Error::DeadlineExceeded exception is thrown.
Exceptions thrown by Sys#sendto method could be thrown.
Exceptions thrown by Go#gosched_io_write method could be thrown (e.g., Go::Error::IOTimeout).
recv
method recv : int ($buffer : mutable string, $length : int = -1, $flags : int = 0, $offset : int = 0);
Performs recv operation by calling "recvfrom" with $from_ref set to undef.
Exceptions:
Exceptions thrown by "recvfrom" method could be thrown.
send
method send : int ($buffer : string, $flags : int = 0, $length : int = -1, $offset : int = 0);
Performs send operation by calling "sendto" with $to set to undef.
Exceptions:
Exceptions thrown by "sendto" method could be thrown.
sysread
method sysread : int ($buffer : mutable string, $length : int = -1, $offset : int = 0);
Perform sysread operation by calling "recv" with $flags set to 0.
Exceptions:
Exceptions thrown by "recv" method could be thrown.
syswrite
method syswrite : int ($buffer : string, $length : int = -1, $offset : int = 0);
Perform syswrite operation by calling "send" with $flags set to 0.
Exceptions:
Exceptions thrown by "send" method could be thrown.
sockname
method sockname : Sys::Socket::Sockaddr ();
Returns a Sys::Socket::Sockaddr for the local address.
Exceptions:
Exceptions thrown by Sys#getsockname method could be thrown.
peername
method peername : Sys::Socket::Sockaddr ();
Returns a Sys::Socket::Sockaddr for the remote address.
Exceptions:
Exceptions thrown by Sys#getpeername method could be thrown.
connected
method connected : Sys::Socket::Sockaddr ();
Checks if the socket is connected. Returns a Sys::Socket::Sockaddr if "peername" succeeds, otherwise returns undef.
atmark
method atmark : int ();
Calls Sys::Socket#sockatmark and returns the result.
Exceptions:
Exceptions thrown by Sys::Socket#sockatmark method could be thrown.
sockopt
method sockopt : int ($level : int, $option_name : int);
Gets a socket option by calling Sys#getsockopt.
Exceptions:
Exceptions thrown by Sys#getsockopt method could be thrown.
setsockopt
method setsockopt : void ($level : int, $option_name : int, $option_value : object of string|Int);
Sets a socket option by calling Sys#setsockopt.
Exceptions:
Exceptions thrown by Sys#setsockopt method could be thrown.
See Also
Porting
This class is a port of Perl's IO::Socket to SPVM.
Copyright & License
Copyright (c) 2026 Yuki Kimoto
MIT License