Class: UNIXServer
- Inherits:
-
UNIXSocket
- Object
- IO
- BasicSocket
- UNIXSocket
- UNIXServer
- Defined in:
- unixserver.c,
unixserver.c,
lib/socket.rb
Overview
UNIXServer represents a UNIX domain stream server socket.
Instance Method Summary collapse
-
#accept ⇒ Object
Accepts an incoming connection.
-
#accept_nonblock(exception: true) ⇒ Object
call-seq: unixserver.accept_nonblock() => unixsocket.
-
#new(path) ⇒ Object
constructor
Creates a new UNIX server socket bound to path.
-
#listen(int) ⇒ 0
Listens for connections, using the specified
int
as the backlog. -
#sysaccept ⇒ Object
Accepts a new connection.
Methods inherited from UNIXSocket
#addr, pair, #path, #peeraddr, #recv_io, #recvfrom, #send_io, socketpair
Methods inherited from BasicSocket
#close_read, #close_write, #connect_address, do_not_reverse_lookup, #do_not_reverse_lookup, do_not_reverse_lookup=, #do_not_reverse_lookup=, for_fd, #getpeereid, #getpeername, #getsockname, #getsockopt, #local_address, #recv, #recv_nonblock, #recvmsg, #recvmsg_nonblock, #remote_address, #send, #sendmsg, #sendmsg_nonblock, #setsockopt, #shutdown
Constructor Details
#new(path) ⇒ Object
Creates a new UNIX server socket bound to path.
serv = UNIXServer.new("/tmp/sock")
s = serv.accept
p s.read
24 25 26 27 28 |
# File 'unixserver.c', line 24
static VALUE
unix_svr_init(VALUE sock, VALUE path)
{
return rsock_init_unixsock(sock, path, 1);
}
|
Instance Method Details
#accept ⇒ Object
Accepts an incoming connection. It returns a new UNIXSocket object.
UNIXServer.open("/tmp/sock") {|serv|
UNIXSocket.open("/tmp/sock") {|c|
s = serv.accept
s.puts "hi"
s.close
p c.read #=> "hi\n"
}
}
47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'unixserver.c', line 47
static VALUE
unix_accept(VALUE sock)
{
rb_io_t *fptr;
struct sockaddr_un from;
socklen_t fromlen;
GetOpenFile(sock, fptr);
fromlen = (socklen_t)sizeof(struct sockaddr_un);
return rsock_s_accept(rb_cUNIXSocket, fptr->fd,
(struct sockaddr*)&from, &fromlen);
}
|
#accept_nonblock(exception: true) ⇒ Object
call-seq:
unixserver.accept_nonblock([]) => unixsocket
Accepts an incoming connection using accept(2) after O_NONBLOCK is set for the underlying file descriptor. It returns an accepted UNIXSocket for the incoming connection.
Example
require ‘socket’ serv = UNIXServer.new(“/tmp/sock”) begin # emulate blocking accept sock = serv.accept_nonblock rescue IO::WaitReadable, Errno::EINTR IO.select() retry end # sock is an accepted socket.
Refer to Socket#accept for the exceptions that may be thrown if the call to UNIXServer#accept_nonblock fails.
UNIXServer#accept_nonblock may raise any error corresponding to accept(2) failure, including Errno::EWOULDBLOCK.
If the exception is Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::ECONNABORTED or Errno::EPROTO, it is extended by IO::WaitReadable. So IO::WaitReadable can be used to rescue the exceptions for retrying accept_nonblock.
By specifying ‘exception: false`, the options hash allows you to indicate that accept_nonblock should not raise an IO::WaitReadable exception, but return the symbol :wait_readable instead.
See
-
UNIXServer#accept
-
Socket#accept
1348 1349 1350 |
# File 'lib/socket.rb', line 1348 def accept_nonblock(exception: true) __accept_nonblock(exception) end |
#listen(int) ⇒ 0
Listens for connections, using the specified int
as the backlog. A call to listen only applies if the socket
is of type SOCK_STREAM or SOCK_SEQPACKET.
Parameter
-
backlog
- the maximum length of the queue for pending connections.
Example 1
require 'socket'
include Socket::Constants
socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )
socket.bind( sockaddr )
socket.listen( 5 )
Example 2 (listening on an arbitrary port, unix-based systems only):
require 'socket'
include Socket::Constants
socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
socket.listen( 1 )
Unix-based Exceptions
On unix based systems the above will work because a new sockaddr
struct is created on the address ADDR_ANY, for an arbitrary port number as handed off by the kernel. It will not work on Windows, because Windows requires that the socket
is bound by calling bind before it can listen.
If the backlog amount exceeds the implementation-dependent maximum queue length, the implementation’s maximum queue length will be used.
On unix-based based systems the following system exceptions may be raised if the call to listen fails:
-
Errno::EBADF - the socket argument is not a valid file descriptor
-
Errno::EDESTADDRREQ - the socket is not bound to a local address, and the protocol does not support listening on an unbound socket
-
Errno::EINVAL - the socket is already connected
-
Errno::ENOTSOCK - the socket argument does not refer to a socket
-
Errno::EOPNOTSUPP - the socket protocol does not support listen
-
Errno::EACCES - the calling process does not have appropriate privileges
-
Errno::EINVAL - the socket has been shut down
-
Errno::ENOBUFS - insufficient resources are available in the system to complete the call
Windows Exceptions
On Windows systems the following system exceptions may be raised if the call to listen fails:
-
Errno::ENETDOWN - the network is down
-
Errno::EADDRINUSE - the socket’s local address is already in use. This usually occurs during the execution of bind but could be delayed if the call to bind was to a partially wildcard address (involving ADDR_ANY) and if a specific address needs to be committed at the time of the call to listen
-
Errno::EINPROGRESS - a Windows Sockets 1.1 call is in progress or the service provider is still processing a callback function
-
Errno::EINVAL - the
socket
has not been bound with a call to bind. -
Errno::EISCONN - the
socket
is already connected -
Errno::EMFILE - no more socket descriptors are available
-
Errno::ENOBUFS - no buffer space is available
-
Errno::ENOTSOC -
socket
is not a socket -
Errno::EOPNOTSUPP - the referenced
socket
is not a type that supports the listen method
See
-
listen manual pages on unix-based systems
-
listen function in Microsoft’s Winsock functions reference
643 644 645 646 647 648 649 650 651 652 653 654 655 |
# File 'socket.c', line 643
VALUE
rsock_sock_listen(VALUE sock, VALUE log)
{
rb_io_t *fptr;
int backlog;
backlog = NUM2INT(log);
GetOpenFile(sock, fptr);
if (listen(fptr->fd, backlog) < 0)
rb_sys_fail("listen(2)");
return INT2FIX(0);
}
|
#sysaccept ⇒ Object
Accepts a new connection. It returns the new file descriptor which is an integer.
UNIXServer.open("/tmp/sock") {|serv|
UNIXSocket.open("/tmp/sock") {|c|
fd = serv.sysaccept
s = IO.new(fd)
s.puts "hi"
s.close
p c.read #=> "hi\n"
}
}
92 93 94 95 96 97 98 99 100 101 102 |
# File 'unixserver.c', line 92
static VALUE
unix_sysaccept(VALUE sock)
{
rb_io_t *fptr;
struct sockaddr_un from;
socklen_t fromlen;
GetOpenFile(sock, fptr);
fromlen = (socklen_t)sizeof(struct sockaddr_un);
return rsock_s_accept(0, fptr->fd, (struct sockaddr*)&from, &fromlen);
}
|