Class: BasicSocket
| Relationships & Source Files | |
| Extension / Inclusion / Inheritance Descendants | |
| 
         Subclasses: 
        
       | 
    |
| Super Chains via Extension / Inclusion / Inheritance | |
| 
         Class Chain: 
        
          self,
           
      ::IO
         | 
    |
| 
         Instance Chain: 
        
          self,
           
      ::IO
         | 
    |
| Inherits: | IO | 
| Defined in: | ext/socket/basicsocket.c, ext/socket/ancdata.c, ext/socket/init.c, ext/socket/lib/socket.rb  | 
    
Overview
BasicSocket is the super class for all the ::Socket classes.
Class Attribute Summary
- 
    
      .do_not_reverse_lookup  ⇒ Boolean 
    
    rw
    
Gets the global do_not_reverse_lookup flag.
 - 
    
      .do_not_reverse_lookup=(bool)  
    
    rw
    
Sets the global do_not_reverse_lookup flag.
 
Class Method Summary
- 
    
      .for_fd(fd)  ⇒ BasicSocket 
    
    
Returns a socket object which contains the file descriptor, fd.
 
Instance Attribute Summary
- 
    
      #do_not_reverse_lookup  ⇒ Boolean 
    
    rw
    
Gets the do_not_reverse_lookup flag of basicsocket.
 - 
    
      #do_not_reverse_lookup=(bool)  
    
    rw
    
Sets the do_not_reverse_lookup flag of basicsocket.
 
Instance Method Summary
- 
    
      #close_read  ⇒ nil 
    
    
Disallows further read using shutdown system call.
 - 
    
      #close_write  ⇒ nil 
    
    
Disallows further write using shutdown system call.
 - 
    
      #connect_address  
    
    
Returns an address of the socket suitable for connect in the local machine.
 - 
    
      #getpeereid  ⇒ Array, egid 
    
    
Returns the user and group on the peer of the UNIX socket.
 - 
    
      #getpeername  ⇒ sockaddr 
    
    
Returns the remote address of the socket as a sockaddr string.
 - 
    
      #getsockname  ⇒ sockaddr 
    
    
Returns the local address of the socket as a sockaddr string.
 - 
    
      #getsockopt(level, optname)  ⇒ socketoption 
    
    
Gets a socket option.
 - 
    
      #local_address  ⇒ addrinfo 
    
    
Returns an
::Addrinfoobject for local address obtained by getsockname. - 
    
      #recv(maxlen[, flags[, outbuf]])  ⇒ mesg 
    
    
Receives a message.
 - 
    
      #recv_nonblock(maxlen [, flags [, buf [, options ]]])  ⇒ mesg 
    
    
Receives up to maxlen bytes from
socketusing recvfrom(2) after O_NONBLOCK is set for the underlying file descriptor. - 
    
      #recvmsg(maxmesglen = nil, flags = 0, maxcontrollen = nil, opts = {})  ⇒ Array, ... 
    
    
recvmsg receives a message using recvmsg(2) system call in blocking manner.
 - 
    
      #recvmsg_nonblock(maxdatalen = nil, flags = 0, maxcontrollen = nil, opts = {})  ⇒ Array, ... 
    
    
recvmsg receives a message using recvmsg(2) system call in non-blocking manner.
 - 
    
      #remote_address  ⇒ addrinfo 
    
    
Returns an
::Addrinfoobject for remote address obtained by getpeername. - 
    
      #send(mesg, flags [, dest_sockaddr])  ⇒ numbytes_sent 
    
    
send mesg via basicsocket.
 - 
    
      #sendmsg(mesg, flags = 0, dest_sockaddr = nil, *controls)  ⇒ numbytes_sent 
    
    
sendmsg sends a message using sendmsg(2) system call in blocking manner.
 - 
    
      #sendmsg_nonblock(mesg, flags = 0, dest_sockaddr = nil, *controls, opts = {})  ⇒ numbytes_sent 
    
    
sendmsg_nonblock sends a message using sendmsg(2) system call in non-blocking manner.
 - 
    
      #setsockopt(level, optname, optval)  
    
    
Sets a socket option.
 - 
    
      #shutdown([how])  ⇒ 0 
    
    
Calls shutdown(2) system call.
 - #__recvmsg(dlen, flags, clen, scm_rights) private
 - #__recvmsg_nonblock(dlen, flags, clen, scm_rights, ex) private
 - #__sendmsg(data, flags, dest_sockaddr, controls) private
 - #__sendmsg_nonblock(data, flags, dest_sockaddr, controls, ex) private
 - #read_nonblock(len, str = nil, exception: true) Internal use only
 - #write_nonblock(buf, exception: true) Internal use only
 - #__read_nonblock(length, buf, ex) private Internal use only
 - #__recv_nonblock(len, flg, str, ex) private Internal use only
 - #__write_nonblock(str, ex) private Internal use only
 
Class Attribute Details
    .do_not_reverse_lookup  ⇒ Boolean  (rw)  
Gets the global do_not_reverse_lookup flag.
BasicSocket.do_not_reverse_lookup  #=> false
  # File 'ext/socket/basicsocket.c', line 674
static VALUE
bsock_do_not_rev_lookup(VALUE _)
{
    return rsock_do_not_reverse_lookup?Qtrue:Qfalse;
}
  .do_not_reverse_lookup=(bool) (rw)
Sets the global do_not_reverse_lookup flag.
The flag is used for initial value of do_not_reverse_lookup for each socket.
s1 = TCPSocket.new("localhost", 80)
p s1.do_not_reverse_lookup                 #=> true
BasicSocket.do_not_reverse_lookup = false
s2 = TCPSocket.new("localhost", 80)
p s2.do_not_reverse_lookup                 #=> false
p s1.do_not_reverse_lookup                 #=> true
  # File 'ext/socket/basicsocket.c', line 696
static VALUE
bsock_do_not_rev_lookup_set(VALUE self, VALUE val)
{
    rsock_do_not_reverse_lookup = RTEST(val);
    return val;
}
  Class Method Details
    .for_fd(fd)  ⇒ BasicSocket   
Returns a socket object which contains the file descriptor, fd.
# If invoked by inetd, STDIN/STDOUT/STDERR is a socket.
STDIN_SOCK = Socket.for_fd(STDIN.fileno)
p STDIN_SOCK.remote_address
  # File 'ext/socket/basicsocket.c', line 24
static VALUE
bsock_s_for_fd(VALUE klass, VALUE fd)
{
    rb_io_t *fptr;
    VALUE sock = rsock_init_sock(rb_obj_alloc(klass), NUM2INT(fd));
    GetOpenFile(sock, fptr);
    return sock;
}
  Instance Attribute Details
    #do_not_reverse_lookup  ⇒ Boolean  (rw)  
Gets the do_not_reverse_lookup flag of basicsocket.
require 'socket'
BasicSocket.do_not_reverse_lookup = false
TCPSocket.open("www.ruby-lang.org", 80) {|sock|
  p sock.do_not_reverse_lookup      #=> false
}
BasicSocket.do_not_reverse_lookup = true
TCPSocket.open("www.ruby-lang.org", 80) {|sock|
  p sock.do_not_reverse_lookup      #=> true
}
  # File 'ext/socket/basicsocket.c', line 594
static VALUE
bsock_do_not_reverse_lookup(VALUE sock)
{
    rb_io_t *fptr;
    GetOpenFile(sock, fptr);
    return (fptr->mode & FMODE_NOREVLOOKUP) ? Qtrue : Qfalse;
}
  #do_not_reverse_lookup=(bool) (rw)
Sets the do_not_reverse_lookup flag of basicsocket.
TCPSocket.open("www.ruby-lang.org", 80) {|sock|
  p sock.do_not_reverse_lookup       #=> true
  p sock.peeraddr                    #=> ["AF_INET", 80, "221.186.184.68", "221.186.184.68"]
  sock.do_not_reverse_lookup = false
  p sock.peeraddr                    #=> ["AF_INET", 80, "carbon.ruby-lang.org", "54.163.249.195"]
}
  # File 'ext/socket/basicsocket.c', line 617
static VALUE
bsock_do_not_reverse_lookup_set(VALUE sock, VALUE state)
{
    rb_io_t *fptr;
    GetOpenFile(sock, fptr);
    if (RTEST(state)) {
	fptr->mode |= FMODE_NOREVLOOKUP;
    }
    else {
	fptr->mode &= ~FMODE_NOREVLOOKUP;
    }
    return sock;
}
  Instance Method Details
#__read_nonblock(length, buf, ex) (private)
# File 'ext/socket/init.c', line 322
VALUE
rsock_read_nonblock(VALUE sock, VALUE length, VALUE buf, VALUE ex)
{
    rb_io_t *fptr;
    long n;
    long len = NUM2LONG(length);
    VALUE str = rsock_strbuf(buf, len);
    char *ptr;
    GetOpenFile(sock, fptr);
    if (len == 0) {
	rb_str_set_len(str, 0);
	return str;
    }
    ptr = RSTRING_PTR(str);
    n = read_buffered_data(ptr, len, fptr);
    if (n <= 0) {
	n = (long)recv(fptr->fd, ptr, len, MSG_DONTWAIT);
	if (n < 0) {
	    int e = errno;
	    if ((e == EWOULDBLOCK || e == EAGAIN)) {
		if (ex == Qfalse) return sym_wait_readable;
		rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE,
					 e, "read would block");
	    }
	    rb_syserr_fail_path(e, fptr->pathv);
	}
    }
    if (n != RSTRING_LEN(str)) {
	rb_str_modify(str);
	rb_str_set_len(str, n);
    }
    if (n == 0) {
	if (ex == Qfalse) return Qnil;
	rb_eof_error();
    }
    return str;
}
  #__recv_nonblock(len, flg, str, ex) (private)
# File 'ext/socket/basicsocket.c', line 660
static VALUE
bsock_recv_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str, VALUE ex)
{
    return rsock_s_recvfrom_nonblock(sock, len, flg, str, ex, RECV_RECV);
}
  #__recvmsg(dlen, flags, clen, scm_rights) (private)
[ GitHub ]# File 'ext/socket/ancdata.c', line 1674
VALUE
rsock_bsock_recvmsg(VALUE sock, VALUE dlen, VALUE flags, VALUE clen,
		    VALUE scm_rights)
{
    VALUE ex = Qtrue;
    return bsock_recvmsg_internal(sock, dlen, flags, clen, scm_rights, ex, 0);
}
  #__recvmsg_nonblock(dlen, flags, clen, scm_rights, ex) (private)
[ GitHub ]# File 'ext/socket/ancdata.c', line 1684
VALUE
rsock_bsock_recvmsg_nonblock(VALUE sock, VALUE dlen, VALUE flags, VALUE clen,
			     VALUE scm_rights, VALUE ex)
{
    return bsock_recvmsg_internal(sock, dlen, flags, clen, scm_rights, ex, 1);
}
  #__sendmsg(data, flags, dest_sockaddr, controls) (private)
[ GitHub ]# File 'ext/socket/ancdata.c', line 1306
VALUE
rsock_bsock_sendmsg(VALUE sock, VALUE data, VALUE flags, VALUE dest_sockaddr,
		    VALUE controls)
{
    return bsock_sendmsg_internal(sock, data, flags, dest_sockaddr, controls,
				  Qtrue, 0);
}
  #__sendmsg_nonblock(data, flags, dest_sockaddr, controls, ex) (private)
[ GitHub ]# File 'ext/socket/ancdata.c', line 1316
VALUE
rsock_bsock_sendmsg_nonblock(VALUE sock, VALUE data, VALUE flags,
			     VALUE dest_sockaddr, VALUE controls, VALUE ex)
{
    return bsock_sendmsg_internal(sock, data, flags, dest_sockaddr,
				  controls, ex, 1);
}
  #__write_nonblock(str, ex) (private)
# File 'ext/socket/init.c', line 365
VALUE
rsock_write_nonblock(VALUE sock, VALUE str, VALUE ex)
{
    rb_io_t *fptr;
    long n;
    if (!RB_TYPE_P(str, T_STRING))
	str = rb_obj_as_string(str);
    sock = rb_io_get_write_io(sock);
    GetOpenFile(sock, fptr);
    rb_io_check_writable(fptr);
    /*
     * As with IO#write_nonblock, we may block if somebody is relying on
     * buffered I/O; but nobody actually hits this because pipes and sockets
     * are not userspace-buffered in Ruby by default.
     */
    if (fptr->wbuf.len > 0) {
	rb_io_flush(sock);
    }
#ifdef __APPLE__
  again:
#endif
    n = (long)send(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str), MSG_DONTWAIT);
    if (n < 0) {
	int e = errno;
#ifdef __APPLE__
	if (e == EPROTOTYPE) {
	    goto again;
	}
#endif
	if (e == EWOULDBLOCK || e == EAGAIN) {
	    if (ex == Qfalse) return sym_wait_writable;
	    rb_readwrite_syserr_fail(RB_IO_WAIT_WRITABLE, e,
				    "write would block");
	}
	rb_syserr_fail_path(e, fptr->pathv);
    }
    return LONG2FIX(n);
}
  
    #close_read  ⇒ nil   
Disallows further read using shutdown system call.
s1, s2 = UNIXSocket.pair
s1.close_read
s2.puts #=> Broken pipe (Errno::EPIPE)
  # File 'ext/socket/basicsocket.c', line 95
static VALUE
bsock_close_read(VALUE sock)
{
    rb_io_t *fptr;
    GetOpenFile(sock, fptr);
    shutdown(fptr->fd, 0);
    if (!(fptr->mode & FMODE_WRITABLE)) {
	return rb_io_close(sock);
    }
    fptr->mode &= ~FMODE_READABLE;
    return Qnil;
}
  
    #close_write  ⇒ nil   
Disallows further write using shutdown system call.
UNIXSocket.pair {|s1, s2|
  s1.print "ping"
  s1.close_write
  p s2.read        #=> "ping"
  s2.print "pong"
  s2.close
  p s1.read        #=> "pong"
}
  # File 'ext/socket/basicsocket.c', line 125
static VALUE
bsock_close_write(VALUE sock)
{
    rb_io_t *fptr;
    GetOpenFile(sock, fptr);
    if (!(fptr->mode & FMODE_READABLE)) {
	return rb_io_close(sock);
    }
    shutdown(fptr->fd, 1);
    fptr->mode &= ~FMODE_WRITABLE;
    return Qnil;
}
  #connect_address
Returns an address of the socket suitable for connect in the local machine.
This method returns self.local_address, except following condition.
- 
IPv4 unspecified address (0.0.0.0) is replaced by IPv4 loopback address (127.0.0.1).
 - 
IPv6 unspecified address (::) is replaced by IPv6 loopback address (::1).
 
If the local address is not suitable for connect, ::SocketError is raised. IPv4 and IPv6 address which port is 0 is not suitable for connect. Unix domain socket which has no path is not suitable for connect.
Addrinfo.tcp("0.0.0.0", 0).listen {|serv|
  p serv.connect_address #=> #<Addrinfo: 127.0.0.1:53660 TCP>
  serv.connect_address.connect {|c|
    s, _ = serv.accept
    p [c, s] #=> [#<Socket:fd 4>, #<Socket:fd 6>]
  }
}
  # File 'ext/socket/lib/socket.rb', line 251
def connect_address addr = local_address afamily = addr.afamily if afamily == Socket::AF_INET raise SocketError, "unbound IPv4 socket" if addr.ip_port == 0 if addr.ip_address == "0.0.0.0" addr = Addrinfo.new(["AF_INET", addr.ip_port, nil, "127.0.0.1"], addr.pfamily, addr.socktype, addr.protocol) end elsif defined?(Socket::AF_INET6) && afamily == Socket::AF_INET6 raise SocketError, "unbound IPv6 socket" if addr.ip_port == 0 if addr.ip_address == "::" addr = Addrinfo.new(["AF_INET6", addr.ip_port, nil, "::1"], addr.pfamily, addr.socktype, addr.protocol) elsif addr.ip_address == "0.0.0.0" # MacOS X 10.4 returns "a.b.c.d" for IPv4-mapped IPv6 address. addr = Addrinfo.new(["AF_INET6", addr.ip_port, nil, "::1"], addr.pfamily, addr.socktype, addr.protocol) elsif addr.ip_address == "::ffff:0.0.0.0" # MacOS X 10.6 returns "::ffff:a.b.c.d" for IPv4-mapped IPv6 address. addr = Addrinfo.new(["AF_INET6", addr.ip_port, nil, "::1"], addr.pfamily, addr.socktype, addr.protocol) end elsif defined?(Socket::AF_UNIX) && afamily == Socket::AF_UNIX raise SocketError, "unbound Unix socket" if addr.unix_path == "" end addr end
    #getpeereid  ⇒ Array, egid   
Returns the user and group on the peer of the UNIX socket. The result is a two element array which contains the effective uid and the effective gid.
Socket.unix_server_loop("/tmp/sock") {|s|
  begin
    euid, egid = s.getpeereid
    # Check the connected client is myself or not.
    next if euid != Process.uid
    # do something about my resource.
  ensure
    s.close
  end
}
  # File 'ext/socket/basicsocket.c', line 421
static VALUE
bsock_getpeereid(VALUE self)
{
#if defined(HAVE_GETPEEREID)
    rb_io_t *fptr;
    uid_t euid;
    gid_t egid;
    GetOpenFile(self, fptr);
    if (getpeereid(fptr->fd, &euid, &egid) == -1)
	rb_sys_fail("getpeereid(3)");
    return rb_assoc_new(UIDT2NUM(euid), GIDT2NUM(egid));
#elif defined(SO_PEERCRED) /* GNU/Linux */
    rb_io_t *fptr;
    struct ucred cred;
    socklen_t len = sizeof(cred);
    GetOpenFile(self, fptr);
    if (getsockopt(fptr->fd, SOL_SOCKET, SO_PEERCRED, &cred, &len) == -1)
	rb_sys_fail("getsockopt(SO_PEERCRED)");
    return rb_assoc_new(UIDT2NUM(cred.uid), GIDT2NUM(cred.gid));
#elif defined(HAVE_GETPEERUCRED) /* Solaris */
    rb_io_t *fptr;
    ucred_t *uc = NULL;
    VALUE ret;
    GetOpenFile(self, fptr);
    if (getpeerucred(fptr->fd, &uc) == -1)
	rb_sys_fail("getpeerucred(3C)");
    ret = rb_assoc_new(UIDT2NUM(ucred_geteuid(uc)), GIDT2NUM(ucred_getegid(uc)));
    ucred_free(uc);
    return ret;
#endif
}
  
    #getpeername  ⇒ sockaddr   
Returns the remote address of the socket as a sockaddr string.
TCPServer.open("127.0.0.1", 1440) {|serv|
  c = TCPSocket.new("127.0.0.1", 1440)
  s = serv.accept
  p s.getpeername #=> "\x02\x00\x82u\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
}
If Addrinfo object is preferred over the binary string, use #remote_address.
# File 'ext/socket/basicsocket.c', line 383
static VALUE
bsock_getpeername(VALUE sock)
{
    union_sockaddr buf;
    socklen_t len = (socklen_t)sizeof buf;
    socklen_t len0 = len;
    rb_io_t *fptr;
    GetOpenFile(sock, fptr);
    if (getpeername(fptr->fd, &buf.addr, &len) < 0)
	rb_sys_fail("getpeername(2)");
    if (len0 < len) len = len0;
    return rb_str_new((char*)&buf, len);
}
  
    #getsockname  ⇒ sockaddr   
Returns the local address of the socket as a sockaddr string.
TCPServer.open("127.0.0.1", 15120) {|serv|
  p serv.getsockname #=> "\x02\x00;\x10\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
}
If Addrinfo object is preferred over the binary string, use #local_address.
# File 'ext/socket/basicsocket.c', line 352
static VALUE
bsock_getsockname(VALUE sock)
{
    union_sockaddr buf;
    socklen_t len = (socklen_t)sizeof buf;
    socklen_t len0 = len;
    rb_io_t *fptr;
    GetOpenFile(sock, fptr);
    if (getsockname(fptr->fd, &buf.addr, &len) < 0)
	rb_sys_fail("getsockname(2)");
    if (len0 < len) len = len0;
    return rb_str_new((char*)&buf, len);
}
  
    #getsockopt(level, optname)  ⇒ socketoption   
Gets a socket option. These are protocol and system specific, see your local system documentation for details. The option is returned as a ::Socket::Option object.
Parameters
- 
levelis an integer, usually one of the SOL_ constants such as Socket::SOL_SOCKET, or a protocol level. A string or symbol of the name, possibly without prefix, is also accepted. - 
optnameis an integer, usually one of the SO_ constants, such as Socket::SO_REUSEADDR. A string or symbol of the name, possibly without prefix, is also accepted. 
Examples
Some socket options are integers with boolean values, in this case #getsockopt could be called like this:
reuseaddr = sock.getsockopt(:SOCKET, :REUSEADDR).bool
optval = sock.getsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR)
optval = optval.unpack "i"
reuseaddr = optval[0] == 0 ? false : true
Some socket options are integers with numeric values, in this case #getsockopt could be called like this:
ipttl = sock.getsockopt(:IP, :TTL).int
optval = sock.getsockopt(Socket::IPPROTO_IP, Socket::IP_TTL)
ipttl = optval.unpack("i")[0]
Option values may be structs. Decoding them can be complex as it involves examining your system headers to determine the correct definition. An example is a struct linger, which may be defined in your system headers as:
struct linger {
  int l_onoff;
  int l_linger;
};
In this case #getsockopt could be called like this:
# Socket::Option knows linger structure.
onoff, linger = sock.getsockopt(:SOCKET, :LINGER).linger
optval =  sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER)
onoff, linger = optval.unpack "ii"
onoff = onoff == 0 ? false : true
  # File 'ext/socket/basicsocket.c', line 303
static VALUE
bsock_getsockopt(VALUE sock, VALUE lev, VALUE optname)
{
    int level, option;
    socklen_t len;
    char *buf;
    rb_io_t *fptr;
    int family;
    GetOpenFile(sock, fptr);
    family = rsock_getfamily(fptr);
    level = rsock_level_arg(family, lev);
    option = rsock_optname_arg(family, level, optname);
    len = 256;
#ifdef _AIX
    switch (option) {
      case SO_DEBUG:
      case SO_REUSEADDR:
      case SO_KEEPALIVE:
      case SO_DONTROUTE:
      case SO_BROADCAST:
      case SO_OOBINLINE:
        /* AIX doesn't set len for boolean options */
        len = sizeof(int);
    }
#endif
    buf = ALLOCA_N(char,len);
    rb_io_check_closed(fptr);
    if (getsockopt(fptr->fd, level, option, buf, &len) < 0)
	rsock_sys_fail_path("getsockopt(2)", fptr->pathv);
    return rsock_sockopt_new(family, level, option, rb_str_new(buf, len));
}
  
    #local_address  ⇒ addrinfo   
Returns an ::Addrinfo object for local address obtained by getsockname.
Note that addrinfo.protocol is filled by 0.
TCPSocket.open("www.ruby-lang.org", 80) {|s|
  p s.local_address #=> #<Addrinfo: 192.168.0.129:36873 TCP>
}
TCPServer.open("127.0.0.1", 1512) {|serv|
  p serv.local_address #=> #<Addrinfo: 127.0.0.1:1512 TCP>
}
  # File 'ext/socket/basicsocket.c', line 473
static VALUE
bsock_local_address(VALUE sock)
{
    union_sockaddr buf;
    socklen_t len = (socklen_t)sizeof buf;
    socklen_t len0 = len;
    rb_io_t *fptr;
    GetOpenFile(sock, fptr);
    if (getsockname(fptr->fd, &buf.addr, &len) < 0)
	rb_sys_fail("getsockname(2)");
    if (len0 < len) len = len0;
    return rsock_fd_socket_addrinfo(fptr->fd, &buf.addr, len);
}
  #read_nonblock(len, str = nil, exception: true)
# File 'ext/socket/lib/socket.rb', line 451
def read_nonblock(len, str = nil, exception: true) # :nodoc: __read_nonblock(len, str, exception) end
    #recv(maxlen[, flags[, outbuf]])  ⇒ mesg   
Receives a message.
maxlen is the maximum number of bytes to receive.
flags should be a bitwise OR of Socket::MSG_* constants.
outbuf will contain only the received data after the method call even if it is not empty at the beginning.
UNIXSocket.pair {|s1, s2|
  s1.puts "Hello World"
  p s2.recv(4)                     #=> "Hell"
  p s2.recv(4, Socket::MSG_PEEK)   #=> "o Wo"
  p s2.recv(4)                     #=> "o Wo"
  p s2.recv(10)                    #=> "rld\n"
}
  # File 'ext/socket/basicsocket.c', line 653
static VALUE
bsock_recv(int argc, VALUE *argv, VALUE sock)
{
    return rsock_s_recvfrom(sock, argc, argv, RECV_RECV);
}
  
    #recv_nonblock(maxlen [, flags [, buf [, options ]]])  ⇒ mesg   
Receives up to maxlen bytes from socket using recvfrom(2) after O_NONBLOCK is set for the underlying file descriptor. flags is zero or more of the MSG_ options. The result, mesg, is the data received.
When recvfrom(2) returns 0, Socket#recv_nonblock returns an empty string as data. The meaning depends on the socket: EOF on TCP, empty packet on UDP, etc.
Parameters
- 
maxlen- the number of bytes to receive from the socket - 
flags- zero or more of theMSG_options - 
buf- destination String buffer - 
options- keyword hash, supportingexception: false 
Example
serv = TCPServer.new("127.0.0.1", 0)
af, port, host, addr = serv.addr
c = TCPSocket.new(addr, port)
s = serv.accept
c.send "aaa", 0
begin # emulate blocking recv.
  p s.recv_nonblock(10) #=> "aaa"
rescue IO::WaitReadable
  IO.select([s])
  retry
end
Refer to Socket#recvfrom for the exceptions that may be thrown if the call to recv_nonblock fails.
recv_nonblock may raise any error corresponding to recvfrom(2) failure, including Errno::EWOULDBLOCK.
If the exception is Errno::EWOULDBLOCK or Errno::EAGAIN, it is extended by IO::WaitReadable. So IO::WaitReadable can be used to rescue the exceptions for retrying recv_nonblock.
By specifying a keyword argument exception to false, you can indicate that recv_nonblock should not raise an IO::WaitReadable exception, but return the symbol :wait_readable instead.
See
# File 'ext/socket/lib/socket.rb', line 371
def recv_nonblock(len, flag = 0, str = nil, exception: true) __recv_nonblock(len, flag, str, exception) end
    #recvmsg(maxmesglen = nil, flags = 0, maxcontrollen = nil, opts = {})  ⇒ Array, ...   
recvmsg receives a message using recvmsg(2) system call in blocking manner.
maxmesglen is the maximum length of mesg to receive.
flags is bitwise OR of MSG_* constants such as Socket::MSG_PEEK.
maxcontrollen is the maximum length of controls (ancillary data) to receive.
opts is option hash. Currently :scm_rights=>bool is the only option.
:scm_rights option specifies that application expects SCM_RIGHTS control message. If the value is nil or false, application don’t expects SCM_RIGHTS control message. In this case, recvmsg closes the passed file descriptors immediately. This is the default behavior.
If :scm_rights value is neither nil nor false, application expects SCM_RIGHTS control message. In this case, recvmsg creates ::IO objects for each file descriptors for Socket::AncillaryData#unix_rights method.
The return value is 4-elements array.
mesg is a string of the received message.
sender_addrinfo is a sender socket address for connection-less socket. It is an ::Addrinfo object. For connection-oriented socket such as TCP, sender_addrinfo is platform dependent.
rflags is a flags on the received message which is bitwise OR of MSG_* constants such as Socket::MSG_TRUNC. It will be nil if the system uses 4.3BSD style old recvmsg system call.
controls is ancillary data which is an array of ::Socket::AncillaryData objects such as:
#<Socket::AncillaryData: AF_UNIX SOCKET RIGHTS 7>
maxmesglen and maxcontrollen can be nil. In that case, the buffer will be grown until the message is not truncated. Internally, MSG_PEEK is used. Buffer full and MSG_CTRUNC are checked for truncation.
recvmsg can be used to implement recv_io as follows:
mesg, sender_sockaddr, rflags, *controls = sock.recvmsg(:scm_rights=>true)
controls.each {|ancdata|
  if ancdata.cmsg_is?(:SOCKET, :RIGHTS)
    return ancdata.unix_rights[0]
  end
}
  # File 'ext/socket/lib/socket.rb', line 426
def recvmsg(dlen = nil, flags = 0, clen = nil, scm_rights: false) __recvmsg(dlen, flags, clen, scm_rights) end
    #recvmsg_nonblock(maxdatalen = nil, flags = 0, maxcontrollen = nil, opts = {})  ⇒ Array, ...   
recvmsg receives a message using recvmsg(2) system call in non-blocking manner.
It is similar to #recvmsg but non-blocking flag is set before the system call and it doesn’t retry the system call.
By specifying a keyword argument exception to false, you can indicate that recvmsg_nonblock should not raise an IO::WaitReadable exception, but return the symbol :wait_readable instead.
# File 'ext/socket/lib/socket.rb', line 442
def recvmsg_nonblock(dlen = nil, flags = 0, clen = nil, scm_rights: false, exception: true) __recvmsg_nonblock(dlen, flags, clen, scm_rights, exception) end
    #remote_address  ⇒ addrinfo   
Returns an ::Addrinfo object for remote address obtained by getpeername.
Note that addrinfo.protocol is filled by 0.
TCPSocket.open("www.ruby-lang.org", 80) {|s|
  p s.remote_address #=> #<Addrinfo: 221.186.184.68:80 TCP>
}
TCPServer.open("127.0.0.1", 1728) {|serv|
  c = TCPSocket.new("127.0.0.1", 1728)
  s = serv.accept
  p s.remote_address #=> #<Addrinfo: 127.0.0.1:36504 TCP>
}
  # File 'ext/socket/basicsocket.c', line 507
static VALUE
bsock_remote_address(VALUE sock)
{
    union_sockaddr buf;
    socklen_t len = (socklen_t)sizeof buf;
    socklen_t len0 = len;
    rb_io_t *fptr;
    GetOpenFile(sock, fptr);
    if (getpeername(fptr->fd, &buf.addr, &len) < 0)
	rb_sys_fail("getpeername(2)");
    if (len0 < len) len = len0;
    return rsock_fd_socket_addrinfo(fptr->fd, &buf.addr, len);
}
  
    #send(mesg, flags [, dest_sockaddr])  ⇒ numbytes_sent   
send mesg via basicsocket.
mesg should be a string.
flags should be a bitwise OR of Socket::MSG_* constants.
dest_sockaddr should be a packed sockaddr string or an addrinfo.
TCPSocket.open("localhost", 80) {|s|
  s.send "GET / HTTP/1.0\r\n\r\n", 0
  p s.read
}
  # File 'ext/socket/basicsocket.c', line 539
VALUE
rsock_bsock_send(int argc, VALUE *argv, VALUE sock)
{
    struct rsock_send_arg arg;
    VALUE flags, to;
    rb_io_t *fptr;
    ssize_t n;
    rb_blocking_function_t *func;
    const char *funcname;
    rb_scan_args(argc, argv, "21", &arg.mesg, &flags, &to);
    StringValue(arg.mesg);
    if (!NIL_P(to)) {
	SockAddrStringValue(to);
	to = rb_str_new4(to);
	arg.to = (struct sockaddr *)RSTRING_PTR(to);
	arg.tolen = RSTRING_SOCKLEN(to);
	func = rsock_sendto_blocking;
	funcname = "sendto(2)";
    }
    else {
	func = rsock_send_blocking;
	funcname = "send(2)";
    }
    GetOpenFile(sock, fptr);
    arg.fd = fptr->fd;
    arg.flags = NUM2INT(flags);
    while (rsock_maybe_fd_writable(arg.fd),
	   (n = (ssize_t)BLOCKING_REGION_FD(func, &arg)) < 0) {
	if (rb_io_wait_writable(arg.fd)) {
	    continue;
	}
	rb_sys_fail(funcname);
    }
    return SSIZET2NUM(n);
}
  
    #sendmsg(mesg, flags = 0, dest_sockaddr = nil, *controls)  ⇒ numbytes_sent   
sendmsg sends a message using sendmsg(2) system call in blocking manner.
mesg is a string to send.
flags is bitwise OR of MSG_* constants such as Socket::MSG_OOB.
dest_sockaddr is a destination socket address for connection-less socket. It should be a sockaddr such as a result of Socket.sockaddr_in. An Addrinfo object can be used too.
controls is a list of ancillary data. The element of controls should be ::Socket::AncillaryData or 3-elements array. The 3-element array should contains cmsg_level, cmsg_type and data.
The return value, numbytes_sent is an integer which is the number of bytes sent.
sendmsg can be used to implement send_io as follows:
# use Socket::AncillaryData.
ancdata = Socket::AncillaryData.int(:UNIX, :SOCKET, :RIGHTS, io.fileno)
sock.sendmsg("a", 0, nil, ancdata)
# use 3-element array.
ancdata = [:SOCKET, :RIGHTS, [io.fileno].pack("i!")]
sock.sendmsg("\0", 0, nil, ancdata)
  # File 'ext/socket/lib/socket.rb', line 303
def sendmsg(mesg, flags = 0, dest_sockaddr = nil, *controls) __sendmsg(mesg, flags, dest_sockaddr, controls) end
    #sendmsg_nonblock(mesg, flags = 0, dest_sockaddr = nil, *controls, opts = {})  ⇒ numbytes_sent   
sendmsg_nonblock sends a message using sendmsg(2) system call in non-blocking manner.
It is similar to #sendmsg but the non-blocking flag is set before the system call and it doesn’t retry the system call.
By specifying a keyword argument exception to false, you can indicate that sendmsg_nonblock should not raise an IO::WaitWritable exception, but return the symbol :wait_writable instead.
# File 'ext/socket/lib/socket.rb', line 319
def sendmsg_nonblock(mesg, flags = 0, dest_sockaddr = nil, *controls, exception: true) __sendmsg_nonblock(mesg, flags, dest_sockaddr, controls, exception) end
    
      #setsockopt(level, optname, optval)  
      #setsockopt(socketoption)  
    
  
Sets a socket option. These are protocol and system specific, see your local system documentation for details.
Parameters
- 
levelis an integer, usually one of the SOL_ constants such as Socket::SOL_SOCKET, or a protocol level. A string or symbol of the name, possibly without prefix, is also accepted. - 
optnameis an integer, usually one of the SO_ constants, such as Socket::SO_REUSEADDR. A string or symbol of the name, possibly without prefix, is also accepted. - 
optvalis the value of the option, it is passed to the underlying setsockopt() as a pointer to a certain number of bytes. How this is done depends on the type:- 
Integer: value is assigned to an int, and a pointer to the int is passed, with length of sizeof(int).
 - 
true or false: 1 or 0 (respectively) is assigned to an int, and the int is passed as for an Integer. Note that
falsemust be passed, notnil. - 
String: the string’s data and length is passed to the socket.
 
 - 
 - 
socketoptionis an instance of::Socket::Option 
Examples
Some socket options are integers with boolean values, in this case #setsockopt could be called like this:
sock.setsockopt(:SOCKET, :REUSEADDR, true)
sock.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)
sock.setsockopt(Socket::Option.bool(:INET, :SOCKET, :REUSEADDR, true))
Some socket options are integers with numeric values, in this case #setsockopt could be called like this:
sock.setsockopt(:IP, :TTL, 255)
sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_TTL, 255)
sock.setsockopt(Socket::Option.int(:INET, :IP, :TTL, 255))
Option values may be structs. Passing them can be complex as it involves examining your system headers to determine the correct definition. An example is an ip_mreq, which may be defined in your system headers as:
struct ip_mreq {
  struct  in_addr imr_multiaddr;
  struct  in_addr imr_interface;
};
In this case #setsockopt could be called like this:
optval = IPAddr.new("224.0.0.251").hton +
         IPAddr.new(Socket::INADDR_ANY, Socket::AF_INET).hton
sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, optval)
  # File 'ext/socket/basicsocket.c', line 197
static VALUE
bsock_setsockopt(int argc, VALUE *argv, VALUE sock)
{
    VALUE lev, optname, val;
    int family, level, option;
    rb_io_t *fptr;
    int i;
    char *v;
    int vlen;
    if (argc == 1) {
        lev = rb_funcall(argv[0], rb_intern("level"), 0);
        optname = rb_funcall(argv[0], rb_intern("optname"), 0);
        val = rb_funcall(argv[0], rb_intern("data"), 0);
    }
    else {
        rb_scan_args(argc, argv, "30", &lev, &optname, &val);
    }
    GetOpenFile(sock, fptr);
    family = rsock_getfamily(fptr);
    level = rsock_level_arg(family, lev);
    option = rsock_optname_arg(family, level, optname);
    switch (TYPE(val)) {
      case T_FIXNUM:
	i = FIX2INT(val);
	goto numval;
      case T_FALSE:
	i = 0;
	goto numval;
      case T_TRUE:
	i = 1;
      numval:
	v = (char*)&i; vlen = (int)sizeof(i);
	break;
      default:
	StringValue(val);
	v = RSTRING_PTR(val);
	vlen = RSTRING_SOCKLEN(val);
	break;
    }
    rb_io_check_closed(fptr);
    if (setsockopt(fptr->fd, level, option, v, vlen) < 0)
        rsock_sys_fail_path("setsockopt(2)", fptr->pathv);
    return INT2FIX(0);
}
  
    #shutdown([how])  ⇒ 0   
Calls shutdown(2) system call.
s.shutdown(Socket::SHUT_RD) disallows further read.
s.shutdown(Socket::SHUT_WR) disallows further write.
s.shutdown(Socket::SHUT_RDWR) disallows further read and write.
how can be symbol or string:
- 
:RD,:SHUT_RD, “RD” and “SHUT_RD” are accepted as Socket::SHUT_RD. - 
:WR,:SHUT_WR, “WR” and “SHUT_WR” are accepted as Socket::SHUT_WR. - 
:RDWR,:SHUT_RDWR, “RDWR” and “SHUT_RDWR” are accepted as Socket::SHUT_RDWR.UNIXSocket.pair {|s1, s2|
s1.puts "ping" s1.shutdown(:WR) p s2.read #=> "ping\n" s2.puts "pong" s2.close p s1.read #=> "pong\n"}
 
# File 'ext/socket/basicsocket.c', line 62
static VALUE
bsock_shutdown(int argc, VALUE *argv, VALUE sock)
{
    VALUE howto;
    int how;
    rb_io_t *fptr;
    rb_scan_args(argc, argv, "01", &howto);
    if (howto == Qnil)
	how = SHUT_RDWR;
    else {
	how = rsock_shutdown_how_arg(howto);
        if (how != SHUT_WR && how != SHUT_RD && how != SHUT_RDWR) {
	    rb_raise(rb_eArgError, "`how' should be either :SHUT_RD, :SHUT_WR, :SHUT_RDWR");
	}
    }
    GetOpenFile(sock, fptr);
    if (shutdown(fptr->fd, how) == -1)
	rb_sys_fail("shutdown(2)");
    return INT2FIX(0);
}
  #write_nonblock(buf, exception: true)
# File 'ext/socket/lib/socket.rb', line 455
def write_nonblock(buf, exception: true) # :nodoc: __write_nonblock(buf, exception) end