類別 UNIXServer
UNIXServer
代表 UNIX 領域串流伺服器 Socket。
公開類別方法
建立新的 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); }
公開實體方法
接受傳入連線。傳回新的 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); }
在為基礎檔案描述符設定 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
使用指定的 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); }
接受新連線。它會傳回新的檔案描述符,為整數。
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); }