類別 UNIXServer

UNIXServer 代表 UNIX 領域串流伺服器 Socket。

公開類別方法

new(path) → unixserver 按一下以切換來源

建立新的 UNIX 伺服器 Socket,繫結至 path

require 'socket'

serv = UNIXServer.new("/tmp/sock")
s = serv.accept
p s.read
static VALUE
unix_svr_init(VALUE sock, VALUE path)
{
    return rsock_init_unixsock(sock, path, 1);
}

公開實體方法

accept → unixsocket 按一下以切換來源

接受傳入連線。傳回新的 UNIXSocket 物件。

UNIXServer.open("/tmp/sock") {|serv|
  UNIXSocket.open("/tmp/sock") {|c|
    s = serv.accept
    s.puts "hi"
    s.close
    p c.read #=> "hi\n"
  }
}
static VALUE
unix_accept(VALUE server)
{
    struct sockaddr_un buffer;
    socklen_t length = sizeof(buffer);

    return rsock_s_accept(rb_cUNIXSocket, server, (struct sockaddr*)&buffer, &length);
}
accept_nonblock([options]) → unixsocket 按一下以切換來源

在為基礎檔案描述符設定 O_NONBLOCK 之後,使用 accept(2) 接受傳入連線。傳回已接受的 UNIXSocket,以供傳入連線使用。

範例

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

請參閱 Socket#accept,以了解在呼叫 UNIXServer#accept_nonblock 失敗時可能會引發的例外狀況。

UNIXServer#accept_nonblock 可能會引發任何與 accept(2) 失敗對應的錯誤,包括 Errno::EWOULDBLOCK。

如果例外狀況是 Errno::EWOULDBLOCK、Errno::EAGAIN、Errno::ECONNABORTED 或 Errno::EPROTO,則會由 IO::WaitReadable 延伸。因此,IO::WaitReadable 可用於救援例外狀況,以重新嘗試 accept_nonblock。

透過將關鍵字引數 exception 指定為 false,您可以指出 accept_nonblock 不應引發 IO::WaitReadable 例外狀況,而是傳回符號 :wait_readable

請參閱

# File ext/socket/lib/socket.rb, line 1360
def accept_nonblock(exception: true)
  __accept_nonblock(exception)
end
listen( int ) → 0 按一下以切換來源

使用指定的 int 作為後備,偵聽連線。呼叫 listen 僅適用於類型為 SOCK_STREAM 或 SOCK_SEQPACKET 的 socket

參數

  • backlog - 處理中連線佇列的最大長度。

範例 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 )

範例 2 (僅在任意埠上偵聽,僅限 Unix 系統):

require 'socket'
include Socket::Constants
socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
socket.listen( 1 )

Unix 系統例外

在 Unix 系統上,上述程式碼會運作,因為會在 ADDR_ANY 位址上建立新的 sockaddr 結構,以取得由核心傳遞的任意埠號。這在 Windows 上無法運作,因為 Windows 要求在 listen 之前,必須呼叫 bind 來繫結 socket

如果 backlog 金額超過與實作相關的最大佇列長度,將會使用實作的最大佇列長度。

在 Unix 系統上,如果呼叫 listen 失敗,可能會產生下列系統例外

  • Errno::EBADF - socket 參數不是有效的檔案描述符

  • Errno::EDESTADDRREQ - socket 未繫結至本機位址,且通訊協定不支援在未繫結的 socket 上偵聽

  • Errno::EINVAL - socket 已連線

  • Errno::ENOTSOCK - socket 參數未參照 socket

  • Errno::EOPNOTSUPP - socket 通訊協定不支援 listen

  • Errno::EACCES - 呼叫程序沒有適當的權限

  • Errno::EINVAL - socket 已關閉

  • Errno::ENOBUFS - 系統中沒有足夠的資源來完成呼叫

Windows 例外

在 Windows 系統上,如果呼叫 listen 失敗,可能會產生下列系統例外

  • Errno::ENETDOWN - 網路已中斷

  • Errno::EADDRINUSE - socket 的本機位址已在使用中。這通常會在執行 bind 期間發生,但如果呼叫 bind 是針對部分萬用字元位址 (包含 ADDR_ANY),且在呼叫 listen 時需要提交特定位址,則可能會延遲。

  • Errno::EINPROGRESS - Windows Sockets 1.1 呼叫正在進行中,或服務提供者仍在處理回呼函式

  • Errno::EINVAL - socket 尚未透過呼叫 bind 來繫結。

  • Errno::EISCONN - socket 已連線

  • Errno::EMFILE - 沒有更多 socket 描述符可用

  • Errno::ENOBUFS - 沒有可用緩衝區空間

  • Errno::ENOTSOC - socket 不是 socket

  • Errno::EOPNOTSUPP - 參考的 socket 不是支援 listen 方法的類型

請參閱

  • 基於 Unix 系統的 listen 手冊頁面

  • Microsoft Winsock 函式參考中的 listen 函式

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 按一下以切換來源

接受新連線。它會傳回新的檔案描述符,為整數。

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"
  }
}
static VALUE
unix_sysaccept(VALUE server)
{
    struct sockaddr_un buffer;
    socklen_t length = sizeof(buffer);

    return rsock_s_accept(0, server, (struct sockaddr*)&buffer, &length);
}