非常教程

Ruby 2.4参考手册

套接字 | Socket

TCPServer

Parent:TCPSocket

TCPServer代表一个TCP / IP服务器套接字。

一个简单的TCP服务器可能如下所示:

require 'socket'

server = TCPServer.new 2000 # Server bind to port 2000
loop do
  client = server.accept    # Wait for a client to connect
  client.puts "Hello !"
  client.puts "Time is #{Time.now}"
  client.close
end

更有用的服务器(服务多个客户端):

require 'socket'

server = TCPServer.new 2000
loop do
  Thread.start(server.accept) do |client|
    client.puts "Hello !"
    client.puts "Time is #{Time.now}"
    client.close
  end
end

公共类方法

new(hostname, port) → tcpserver Show source

创建绑定到端口的新服务器套接字。

如果给出主机名,套接字直接就能绑定到它。

serv = TCPServer.new("127.0.0.1", 28561)
s = serv.accept
s.puts Time.now
s.close

在内部,:: new调用getaddrinfo()函数来获取地址。如果getaddrinfo()返回多个地址,则:: new尝试为每个地址创建一个服务器套接字并返回第一个成功的套接字。

static VALUE
tcp_svr_init(int argc, VALUE *argv, VALUE sock)
{
    VALUE hostname, port;

    rb_scan_args(argc, argv, "011", &hostname, &port);
    return rsock_init_inetsock(sock, hostname, port, Qnil, Qnil, INET_SERVER);
}

公共实例方法

accept → tcpsocket Show source

接受传入的连接。它返回一个新的TCPSocket对象。

TCPServer.open("127.0.0.1", 14641) {|serv|
  s = serv.accept
  s.puts Time.now
  s.close
}
static VALUE
tcp_accept(VALUE sock)
{
    rb_io_t *fptr;
    union_sockaddr from;
    socklen_t fromlen;

    GetOpenFile(sock, fptr);
    fromlen = (socklen_t)sizeof(from);
    return rsock_s_accept(rb_cTCPSocket, fptr->fd, &from.addr, &fromlen);
}

accept_nonblock(options) → tcpsocket Show source

在为基础文件描述符设置O_NONBLOCK后,使用accept(2)接受传入连接。它为传入的连接返回一个可接受的TCPSocket。

require 'socket'
serv = TCPServer.new(2202)
begin # emulate blocking accept
  sock = serv.accept_nonblock
rescue IO::WaitReadable, Errno::EINTR
  IO.select([serv])
  retry
end
# sock is an accepted socket.

如果调用#accept_nonblock失败,请参阅Socket#accept以了解可能会抛出的异常。

#accept_nonblock可能引发与accept(2)失败相对应的任何错误,包括Errno :: EWOULDBLOCK。

如果这个异常是Errno :: EWOULDBLOCK,Errno :: EAGAIN,Errno :: ECONNABORTED,Errno :: EPROTO,则它由IO :: WaitReadable扩展。所以IO :: WaitReadable可以用来解救重试accept_nonblock的异常。

通过指定关键字参数异常false,你可以指出#accept_nonblock应该不会引发IO :: WaitReadable异常,但返回的符号:wait_readable来代替。

参阅

  • #accept
  • Socket#accept
# File ext/socket/lib/socket.rb, line 1296
def accept_nonblock(exception: true)
  __accept_nonblock(exception)
end

listen( int ) → 0 Show source

侦听连接,使用指定的int作为积压。 只有在套接字类型为SOCK_STREAM或SOCK_SEQPACKET的情况下才能调用侦听。

参数

  • backlog - 等待连接队列的最大长度。
  • 示例1需要'套接字'包括
  • Socket::Constants socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' ) socket.bind( sockaddr ) socket.listen( 5 )
  • 示例2(侦听任意端口,仅基于unix的系统):require'socket'include Socket :: Constants socket = Socket.new(AF_INET,SOCK_STREAM,0)socket.
  • listen(1)基于Unix的ExceptionsOn基于unix的系统上述工作将会生效,因为在地址ADDR_ANY上创建了一个新的sockaddr结构,用于由内核传递的任意端口号。它不会在Windows上运行,因为Windows要求socket通过调用约束绑定,才可以进行。如果积压数量超过实现相关的最大队列长度时,将使用实现的最大队列长度。在基于unix的系统上,如果侦听调用失败,则可能会引发以下系统异常:
  • Errno :: EBADF - 套接字参数不是有效的文件描述符
  • Errno :: EDESTADDRREQ - 套接字未绑定到本地地址,且协议不支持侦听未绑定的套接字
  • Errno :: EINVAL - 套接字已经连接
  • Errno :: ENOTSOCK - 套接字参数不引用套接字
  • Errno :: EOPNOTSUPP - 套接字协议不支持listen
  • Errno :: EACCES - 调用过程没有适当的权限
  • Errno :: EINVAL - 套接字 已关闭
  • Errno :: ENOBUFS - 系统中可用资源不足以完成callWindows异常在Windows系统中,如果侦听 呼叫失败,可能会引发以下系统异常:
  • Errno :: ENETDOWN - 网络已关闭
  • Errno :: EADDRINUSE - 套接字的本地地址已被使用。这通常发生在执行绑定期间,但如果绑定 调用是部分通配符地址(涉及ADDR_ANY),并且在调用时需要提交特定地址以便侦听
  • Errno :: EINPROGRESS - 正在进行Windows套接字1.1调用,或者服务提供者仍在处理回调函数
  • Errno :: EINVAL - socket尚未绑定调用绑定
  • Errno :: EISCONN - socket已连接
  • Errno :: EMFILE - 没有套接字描述符处于可用状态
  • Errno :: ENOBUFS - 没有可用的缓冲空间
  • Errno :: ENOTSOC - socket不是套接字
  • Errno :: EOPNOTSUPP - 引用的socket不是支持listen方法的类型

参阅

  • 在基于Unix的系统上收听手册页面
  • 在Microsoft的Winsock函数参考中的监听函数
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 → file_descriptor Show source

返回接受连接的文件描述符。

TCPServer.open("127.0.0.1", 28561) {|serv|
  fd = serv.sysaccept
  s = IO.for_fd(fd)
  s.puts Time.now
  s.close
}
static VALUE
tcp_sysaccept(VALUE sock)
{
    rb_io_t *fptr;
    union_sockaddr from;
    socklen_t fromlen;

    GetOpenFile(sock, fptr);
    fromlen = (socklen_t)sizeof(from);
    return rsock_s_accept(0, fptr->fd, &from.addr, &fromlen);
}
Ruby 2.4

Ruby 是一种面向对象、命令式、函数式、动态的通用编程语言,是世界上最优美而巧妙的语言。

主页 https://www.ruby-lang.org/
源码 https://github.com/ruby/ruby
版本 2.4
发布版本 2.4.1

Ruby 2.4目录

1.缩略 | Abbrev
2.ARGF
3.数组 | Array
4.Base64
5.基本对象 | BasicObject
6.基准测试 | Benchmark
7.BigDecimal
8.绑定 | Binding
9.CGI
10.类 | Class
11.比较 | Comparable
12.负责 | Complex
13.计算续体 | Continuation
14.覆盖 | Coverage
15.CSV
16.日期 | Date
17.日期时间 | DateTime
18.DBM
19.代理 | Delegator
20.摘要 | Digest
21.Dir
22.DRb
23.编码 | Encoding
24.枚举 | Enumerable
25.枚举 | Enumerator
26.ENV
27.ERB
28.错误 | Errors
29.Etc
30.期望值 | Exception
31.错误类 | FalseClass
32.Fiber
33.Fiddle
34.文件 | File
35.文件实用程序 | FileUtils
36.查找 | Find
37.浮点 | Float
38.Forwardable
39.GC
40.GDBM
41.GetoptLong
42.Hash
43.Integer
44.IO
45.IPAddr
46.JSON
47.Kernel
48.语言 | 3Language
49.记录 | Logger
50.编排 | Marshal
51.MatchData
52.数学 | Math
53.矩阵 | Matrix
54.方法 | Method
55.模型 | Module
56.监控 | Monitor
57. 互斥 | Mutex
58.Net
59.Net::FTP
60.Net::HTTP
61.Net::IMAP
62.Net::SMTP
63.NilClass
64.数字 | Numeric
65.对象 | Object
66.ObjectSpace
67.Observable
68.Open3
69.OpenSSL
70.OpenStruct
71.OpenURI
72.OptionParser
73.路径名 | Pathname
74.完整输出 | PrettyPrint
75.Prime
76.Proc
77.过程 | Process
78.PStore
79.PTY
80.队列 | Queue
81.随机 | Random
82.范围 | Range
83.合理的 | Rational
84.Readline
85.Regexp
86.Resolv
87.Ripper
88.RubyVM
89.Scanf
90.SDBM
91.SecureRandom
92.Set
93.Shell
94.信号 | Signal
95.Singleton
96.套接字 | Socket
97.字符串 | String
98.StringIO
99.StringScanner
100.结构 | Struct