Provided by:
manpages-zh_1.5.1-2_all 
NAMEW稱
accept - 在一荇M接字上接收一茬s接
SYNOPSISz
#include <sys/types.h>
#include <sys/socket.h>
int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
DESCRIPTIONyz
accept 函數用於基於連接的套接字 (SOCK_STREAM, SOCK_SEQPACKET 和
SOCK_RDM). 它從未完成連接隊列中取出第一茬s接請求,創建一茤M參數 s
屬性相同的連接套接字,並為這荇M接字分配一蚗仵袨yz符, 然後以這荋y-
z符返回.新創建的描z符不再處於傾聽狀態. 套接字 s
不受此調用的影響.注意任意一蚗仵袨yz符標誌 (任何可以被 fcntl以參數
F_SETFL 設置的,比如非阻塞式或者異步狀態)不會被 accept. 所繼承.
參數 s 是以 socket(2) 創建,用 bind(2) 綁定到一茈誚a地址,並且在調用了
listen(2). 之後正在偵聽一茬s接的套接字. 參數 addr 是一-
茷向結構sockaddr的指針.這茧硎c體以連接實體地址填充.
所謂的連接實體,就是眾所周知的網路層.參數 addr
所傳遞的真正的地址格式依賴於所使用的套接字族. (參見 socket(2)
和各協議自己的手冊). addrlen 是一蚢禤仱捊:
它的大小應該能夠足以容納參數 addr
所指向的結構體;在函數返回時此參數將以字節數表示出返回地址的 實際長度.Y
addr 使用NULL作為參數,addrlen將也被置為NULL.
如果隊列中沒有未完成連接套接字,並且套接字沒有標記為非阻塞式, accept
將阻塞直到一茬s接到達.如果一荇M接字被標記為非阻塞式而隊列
中沒有未完成連接套接字, accept 將返回EAGAIN.
使用 select(2) 或者 poll(2). 可以在一-
荇M接字上有連接到來時產生事件.當嘗試一虓s的連接時 套接字讀就緒,這樣我-
抴N可以調用 accept 為這茬s接獲得一-
虓s的套接字.此外,你還可以設置套接字在喚醒時 接收到信號 SIGIO;
細節請參見 socket(7)
對於那些需n顯式確認的協議,比如 DECNet, accept
可以看作僅僅從隊列中取出下一茬s接而不做確認.當在這虓s的檔案 描-
z符上進行普通讀寫操作時暗示了確認,當關閉這虓s的套接字時暗
示了拒絕.目前在Linux上只有DECNet有這樣 的含義.
NOTES`N
當接收到一 SIGIO 信號或者 select(2) 或 poll(2)
返回讀就緒並不總是意味著有新連接在等待,因為連接可能在調用 accept
之前已經被異步網路錯誤或者其他線程所移除.如果發生這種情況,
那麼調用將阻塞並等待下一茬s接的到來.為確保 accept
永遠不會阻塞,傳遞的套接字 s 需n置 O_NONBLOCK 標誌(參見 socket(7)).
RETURN VALUE^
此調用在發生錯誤時返回-1.Y成市h返回一茷Dt整數標識這 連接套接字.
ERROR HANDLING~Bz
Linux accept 將一茷摀B理網路錯誤代碼通過 accept 傳遞給新套接字 .
這種處理方式有別於其他的BSD套接字實現.為可靠操作,應用程式 必須在調用
accept 之後能夠檢測這些為協議定義的網路錯誤,並且以姜楖悃M,就像 EAGAIN
一樣.對於TCP/IP這些網路錯誤是 ENETDOWN, EPROTO, ENOPROTOOPT, EHOSTDOWN,
ENONET, EHOSTUNREACH, EOPNOTSUPP, 以及 ENETUNREACH.
ERRORS~
EAGAINWOULDBLOCK
套接字被標記為非阻塞,且當前沒有可接收的連接.
EBADF 描z符非法.
ENOTSOCK
描z符指向一蚗仵,而不是一荇M接字.
EOPNOTSUPP
作為參數的套接字不是 SOCK_STREAM. 類型
EFAULT 參數 addr 不在使用者可寫地址空間之內.
EPERM 防火牆規則禁止連接.
ENOBUFS,ENOMEM
沒有足夠記憶體. 這-
蚇欞~一般來說意味著記憶體分配受套接字緩沖區所,
而不是沒有系統記憶體.
另外,新套接字和協議中定義的網路錯誤也可能被返回.
不同的Linux核心也可能返回下列錯誤 EMFILE, EINVAL, ENOSR, ENOBUFS,
EPERM, ECONNABORTED, ESOCKTNOSUPPORT, EPROTONOSUPPORT, ETIMEDOUT,
ERESTARTSYS.
CONFORMING TOe於
SVr4,4.4BSD( accept 函數漲艇X現於BSD 4.2). BSD手冊隊憟顝w義了-
茈i能的錯誤返回 (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所返回的套接字上設置所有需n的標誌.
NOTE`N
函數 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 (譯注:這-
荇a伙就是Linux的創始人,所以我保留了他老人家的鴗, 僅將鴗憭j意附後): 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開始的時唹峈漪Osize_t, Linus
Torvalds(他希望有更多的人,但顯然不是很多) 努力向他-
抶挭嬤洏姠ize_t是完全錯誤的,因為在64位結構中
size_t和int的長度是不一樣的,而這荌捊(也就是accept函數
的第三參數)的長度必須和int一P,因為這是BSD套接字接口
標準.最終POSIX的那幫家伙找到了解決的辦法,那就是創造了 一-
虓s的類型"socklen_t".Linux Torvalds說這是由於他
發現了自己的錯誤但又不好意思向大家伙兒承認,所以另外 創造了一-
虓s的數據類型.
SEE ALSO見
bind(2), connect(2), listen(2), select(2), socket(2)
[]
byeyear <love_my_love@263.net >
[]
2002.01.27
mlinuxan:
http://cmpp.linuxforum.net