Provided by: manpages-zh_1.6.4.0-1_all bug

NAME 名稱

       accept - 在一個套接字上接收一個連線

SYNOPSIS 概述

       #include <sys/types.h>
       #include <sys/socket.h>

       int accept(int s, struct sockaddr *addr, socklen_t *addrlen);

DESCRIPTION 描述

       accept 函式用於基於連線的套接字 (SOCK_STREAM, SOCK_SEQPACKETSOCK_RDM).  它從未完成連線
       佇列中取出第一個連線請求,建立一個和引數 s  屬性相同的連線套接字,併為這個套接字分配一個檔案
       描述符,  然後以這個描述符返回.新建立的描述符不再處於傾聽狀態.原  套接字  s  不受此呼叫的影
       響.注意任意一個檔案描述符標誌 (任何可以被 fcntl以引數 F_SETFL  設定的值,比如非阻塞式或者非
       同步狀態)不會被 accept.  所繼承.

       引數 s 是以 socket(2) 建立,用 bind(2) 繫結到一個本地地址,並且在呼叫了 listen(2).  之後正在
       偵聽一個連線的套接字.  引數  addr  是一個指向結構sockaddr的指標.這個結構體以連線實體地址填
       充.   所謂的連線實體,就是眾所周知的網路層.引數 addr 所傳遞的真正的地址格式依賴於所使用的套
       接字族.  (參見 socket(2) 和各協議自己的手冊頁).  addrlen 是一個實時引數:  它的大小應該能夠
       足以容納引數   addr  所指向的結構體;在函式返回時此引數將以位元組數表示出返回地址的  實際長
       度.若 addr 使用NULL作為引數,addrlen將也被置為NULL.

       如果佇列中沒有未完成連線套接字,並且套接字沒有標記為非阻塞式,  accept  將阻塞直到一個連線到
       達.如果一個套接字被標記為非阻塞式而佇列 中沒有未完成連線套接字, accept 將返回EAGAIN.

       使用  select(2) 或者 poll(2).  可以在一個套接字上有連線到來時產生事件.當嘗試一個新的連線時
       套接字讀就緒,這樣我們就可以呼叫 accept  為這個連接獲得一個新的套接字.此外,你還可以設定套接
       字在喚醒時 接收到訊號 SIGIO; 細節請參見 socket(7)

       對於那些需要顯式確認的協議,比如  DECNet, accept 可以看作僅僅從佇列中取出下一個連線而不做確
       認.當在這個新的檔案  描述符上進行普通讀寫操作時暗示了確認,當關閉這個新的套接字時暗  示了拒
       絕.目前在Linux上只有DECNet有這樣 的含義.

NOTES 注意

       當接收到一個 SIGIO 訊號或者 select(2) 或 poll(2) 返回讀就緒並不總是意味著有新連線在等待,因
       為連線可能在呼叫 accept 之前已經被非同步網路錯誤或者其他執行緒所移除.如果發生這種情況,  那
       麼呼叫將阻塞並等待下一個連線的到來.為確保   accept   永遠不會阻塞,傳遞的套接字   s  需要置
       O_NONBLOCK 標誌(參見 socket(7)).

RETURN VALUE 返回值

       此呼叫在發生錯誤時返回-1.若成功則返回一個非負整數標識這個 連線套接字.

ERROR HANDLING 錯誤處理

       Linux accept 將一個待處理網路錯誤程式碼透過 accept 傳遞給新套接字 .   這種處理方式有別於其
       他的BSD套接字實現.為可靠操作,應用程式 必須在呼叫 accept 之後能夠檢測這些為協議定義的網路錯
       誤,並且以重試解決,就象 EAGAIN 一樣.對於TCP/IP這些網路錯誤是 ENETDOWN, EPROTO, ENOPROTOOPT,
       EHOSTDOWN, ENONET, EHOSTUNREACH, EOPNOTSUPP, 以及 ENETUNREACH.

ERRORS 錯誤

       EAGAIN或者EWOULDBLOCK
              套接字被標記為非阻塞,且當前沒有可接收的連線.

       EBADF  描述符非法.

       ENOTSOCK
              描述符指向一個檔案,而不是一個套接字.

       EOPNOTSUPP
              作為引數的套接字不是 SOCK_STREAM.  型別

       EFAULT 引數 addr 不在使用者可寫地址空間之內.

       EPERM  防火牆規則禁止連線.

       ENOBUFS,ENOMEM
              沒有足夠記憶體.  這個錯誤一般來說意味著記憶體分配受套接字緩衝區所限, 而不是沒有系統
              記憶體.

       另外,新套接字和協議中定義的網路錯誤也可能被返回.         不同的Linux核心也可能返回下列錯誤
       EMFILE,  EINVAL,  ENOSR,  ENOBUFS,  EPERM, ECONNABORTED, ESOCKTNOSUPPORT, EPROTONOSUPPORT,
       ETIMEDOUT, ERESTARTSYS.

CONFORMING TO 兼容於

       SVr4,4.4BSD(  accept  函式首次出現於BSD   4.2).    BSD手冊頁文件定義了五個可能的錯誤返回值
       (EBADF,  ENOTSOCK,  EOPNOTSUPP,  EWOULDBLOCK,  EFAULT).   SUSv2文件的定義是EAGAIN,  EBADF,
       ECONNABORTED, EFAULT, EINTR, EINVAL, EMFILE, ENFILE,  ENOBUFS,  ENOMEM,  ENOSR,  ENOTSOCK,
       EOPNOTSUPP, EPROTO, EWOULDBLOCK.

       Linux  accept不繼承象  O_NONBLOCK  這樣的套接字標誌.  這一點有別於其他的BSD套接字實現.  因
       此,程式應該在accept所返回的套接字上設定所有需要的標誌.

NOTE 注意

       函式  accept  的第三個引數原來被宣告為'int  *'(在libc4和libc5以及其他很多系統中,   比如BSD
       4.*,SunOS  4,  SGI);POSIX  1003.1g草案試圖將其改變為 `size_t *',SunOS 5就是這麼做的.  後來
       的POSIX草案和Single  Unix  Specification以及glibc2使用了  `socklen_t  *'.   Quoting  Linus
       Torvalds:  引自Linus  Torvalds (譯註:這個傢伙就是Linux的創始人,所以我保留了他老人家的原文,
       僅將原文大意附後): I fails: only italicizes a single line _Any_ sane library  _must_  have
       "socklen_t"  be  the  same  size as int.  Anything else breaks any BSD socket layer stuff.
       POSIX initially _did_ make it a size_t, and I (and hopefully others, but obviously not too
       many)  complained  to  them  very loudly indeed.  Making it a size_t is completely broken,
       exactly because size_t very seldom is the same size as "int" on 64-bit architectures,  for
       example.   And  it  _has_  to be the same size as "int" because that's what the BSD socket
       interface is.  Anyway, the POSIX people eventually got a clue,  and  created  "socklen_t".
       They  shouldn't  have touched it in the first place, but once they did they felt it had to
       have a named type for some unfathomable reason (probably somebody didn't like losing  face
       over having done the original stupid thing, so they silently just renamed their blunder).

       資料型別"socklen_t"和int應該具有相同的長度.否則就會破壞  BSD套接字層的填充.POSIX開始的時候
       用的是size_t, Linus Torvalds(他希望有更多的人,但顯然不是很多) 努力向他們解釋使用size_t是完
       全錯誤的,因為在64位結構中 size_t和int的長度是不一樣的,而這個引數(也就是accept函式 的第三引
       數)的長度必須和int一致,因為這是BSD套接字介面 標準.最終POSIX的那幫傢伙找到了解決的辦法,那就
       是創造了 一個新的型別"socklen_t".Linux Torvalds說這是由於他們 發現了自己的錯誤但又不好意思
       向大家夥兒承認,所以另外 創造了一個新的資料型別.

SEE ALSO 參見

       bind(2), connect(2), listen(2), select(2), socket(2)

[中文版維護人]

       byeyear <love_my_love@263.net >

[中文版最新更新]

       2002.01.27

《中國linux論壇man手冊頁翻譯計劃》:

       http://cmpp.linuxforum.net

       本頁面中文版由中文 man 手冊頁計劃提供。
       中文 man 手冊頁計劃:https://github.com/man-pages-zh/manpages-zh