Socket

该类提供了对套接字进行系统调用的功能。它与Perl调用套接字的功能非常类似。在该类中,使用被pack的字符串来指定套接字地址 (请参考将套接字地址结构体打包成字符串)。

通常进行套接字编程时,都会使用诸如TCPSocketTCPServer这种高层类,而不会用到该类。

超类:

类方法:

Socket.open(domain, type, protocol)
Socket.new(domain, type, protocol)

生成新的套接字。使用include file中的常数来指定domaintypeprotocol。大部分常数都被定义成Socket类中的常数,如Socket::AF_INET等。另外,您也可以使用字符串来指定domaintype,如"AF_INET", "SOCK_STREAM"等。但此时无法保证所有功能的可用性。

Socket.for_fd(fd)

为文件描述符fd生成新的套接字。

ruby 1.7 特性: 该方法已被转移到BasicSocket之中。

Socket.getaddrinfo(nodename, servname[, family[, socktype[, protocol[, flags]]]])

该类方法提供了RFC 2553中定义的getaddrinfo()的功能。该方法取代了gethostbyname()getservbyname(),它是为编写与IP版本无关的程序而准备的标准API。

它返回地址信息的数组。该数组包含以下7各元素。

  • 第0元素 - address family(String)。
  • 第1元素 - 端口号(Integer)。
  • 第2元素 - 主机名(String)。
  • 第3元素 - 地址(String)。
  • 第4元素 - 与address family相对应的Integer。
  • 第5元素 - 与套接字类型相对应的Integer。
  • 第6元素 - 与协议相对应的Integer。

必选参数的意义如下。

其余参数都是可选的。

  • family - address family。 使用address family中的常数,如Socket::AF_INET等进行指定。
  • socktype - 套接字类型。 使用套接字类型中的常数,如Socket::SOCK_STREAM等进行指定。
  • protocol - 协议。 使用协议中的常数,如Socket::IPPROTO_IP等进行指定。
  • flags - Fixnum。它相当于传给getaddrinfo(3)第3参数的 addrinfo结构体中的ai_flags成员。 有时可能会给出Socket::AI_PASSIVESocket::AI_CANONNAMESocket::AI_NUMERICHOST供您选用。

请参考getaddrinfo(3)来了解可用在参数中的常数的具体含义。

例:

p Socket.getaddrinfo(Socket.gethostname, "ftp")
#=> [["AF_INET", 21, "helium.ruby-lang.org", "210.251.121.214", 2, 1, 6]]

pp Socket.getaddrinfo(Socket.gethostname, nil)
#=> [["AF_INET", 0, "helium.ruby-lang.org", "210.251.121.214", 2, 1, 6],
#    ["AF_INET", 0, "helium.ruby-lang.org", "210.251.121.214", 2, 2, 17],
#    ["AF_INET", 0, "helium.ruby-lang.org", "210.251.121.214", 2, 3, 0]]
Socket.getnameinfo(sa[, flags])

该类方法提供了RFC 2553中定义的getnameinfo()的功能。该方法取代了gethostbyaddr()getservbyport(),它是为编写与IP版本无关的程序而准备的标准API。

它返回数组,数组元素是由地址和表示端口的字符串所组成的。

可以将字符串或数组传给参数sa。若是字符串的话,就把sockaddr结构体打包后的字符串传给它。具体说来,可以使用getsockaddr的值。若使用数组的话,有两种选择。

  • 包含3个元素的数组:

    [address family, 服务, 主机]
    
  • 包含4个元素的数组:

    [address family, 服务, 任意, 表示地址表的字符串]
    

既可以使用Socket::AF_INET等常数来指定address family,又可以使用"AF_INET""AF_INET6"nil等字符串来进行指定。若编译时禁用了IPv6的话,"AF_INET6"将失去效力。另外,向address family指定nilnil的效果相同。

至于指定服务和主机等问题,请您参考指定服务指定主机

即使是在包含3个元素的数组中,您也可以把地址指定给主机,但若在包含4个元素的数组中,则可以保证最后一个元素中不会进行名字分解(name resolution)。

传给可选的第2参数flags中的是Fixnum,它相当于getnameinfo(3)第7参数中的flags。

有时会提供Socket::NI_MAXHOSTSocket::NI_MAXSERVSocket::NI_NOFQDNSocket::NI_NUMERICHOSTSocket::NI_NAMEREQDSocket::NI_NUMERICSERVSocket::NI_DGRAM等常数来传给flags参数。

请参考getnameinfo(3)来了解这些常数的含义。

例:

Socket.getnameinfo(Socket.sockaddr_in('21','127.0.0.1'))
#=> ["localhost", "ftp"]

Socket.getnameinfo([nil, 21,'127.0.0.1'])
#=> ["localhost", "ftp"]
Socket.gethostbyaddr(host[, type])

利用sockaddr结构体的打包字符串来返回主机信息。主机信息的结构与Socket.gethostbyname相同。传给type的是地址类型(默认值为Socket::AF_INET)。

Socket.gethostbyname(host)

利用主机名或IP地址(请参考指定主机来了解其指定方法)来获取主机信息,并以数组形式将其返回。主机信息数组包含以下4个元素。

  • 主机名
  • 主机别名的数组
  • 主机地址类型 (整数常数)
  • 主机地址

最后的主机地址采用的是 与各地址类型相对应的 C地址结构体打包字符串的形式。例如,若地址类型为AF_INET(常数2),则可以使用Socket.unpack_sockaddr_in进行unpack。

例:
irb(main):009:0> Socket.gethostbyname("210.251.121.214")
["helium.ruby-lang.org", ["helium"], 2, "\322\373y\326"]

irb(main):009:0> Socket.unpack_sockaddr_in(Socket.gethostbyname("210.251.121.214")[3])[1]
"210.251.121.214"
Socket.gethostname

获取系统的标准主机名。若想获取主机別名或地址等其他信息时,请使用Socket.getaddrinfo

p Socket.gethostname   #=> "helium.ruby-lang.org"
Socket.getservbyname(service[, proto])

返回与serviceproto相对应的端口号。proto的缺省值是"tcp"

Socket.sockaddr_in(port, host) ((<ruby 1.7 特性>))
Socket.pack_sockaddr_in(port, host) ((<ruby 1.7 特性>))

套接字地址结构体的打包字符串形式返回指定的地址。port既可以是表示端口号的Fixnum,又可以是表示端口号或服务名的字符串。

require 'socket'
p Socket.pack_sockaddr_in("echo", "localhost")
=> "\002\000\000\a\177\000\000\001\000\000\000\000\000\000\000\000"
Socket.sockaddr_un(path) ((<ruby 1.7 特性>))
Socket.pack_sockaddr_un(path) ((<ruby 1.7 特性>))

套接字地址结构体的打包字符串形式返回指定的地址。

require 'socket'
p Socket.pack_sockaddr_un("/tmp/.X11-unix/X0")
=> "\001\000/tmp/.X11-unix/X0\000...."
Socket.pair(domain, type, protocol)
Socket.socketpair(domain, type, protocol)

以数组的形式返回相互连接的2个套接字。参数的用法与Socket.open相同。

Socket.unpack_sockaddr_in(addr) ((<ruby 1.7 特性>))

打开(unpack)套接字地址结构体的打包字符串并返回地址。返回值是形如[port, ipaddr]的数组。

require 'socket'
p Socket.unpack_sockaddr_in(Socket.pack_sockaddr_in("echo", "localhost"))
=> [7, "127.0.0.1"]
Socket.unpack_sockaddr_un(addr) ((<ruby 1.7 特性>))

打开(unpack)套接字地址结构体的打包字符串并返回套接字路径名。

require 'socket'
p Socket.unpack_sockaddr_un(Socket.pack_sockaddr_un("/tmp/.X11-unix/X0"))
=> "/tmp/.X11-unix/X0"

方法:

accept

受理新的连接,并返回新连接的套接字和地址。请参考accept(2)

bind(addr)

将套接字绑定到addr上。其运作等同于bind(2)addr套接字地址结构体的打包字符串

connect(addr)

connect(2)相同。addr套接字地址结构体的打包字符串

listen(backlog)

listen(2)相同。

recvfrom(len[, flags])

recv相同,它从套接字那里接收数据,其返回值是字符串和对方套接字的地址。参数的用法与recv相同。

sysaccept ((<ruby 1.7 特性>))

accept大体相同,但它会返回已连接的客户端的文件描述符和地址。