Linux 2.2 Page
7 May 1999
Aliases: accept4(2), accept4(2), accept4(2), accept4(2), accept4(2), accept4(2), accept4(2), accept4(2), accept4(2), accept4(2)
manpages-zh
Chinese manual pages
man-pages-zh_tw
Traditional Chinese Linux man pages
manpages-dev
Manual pages about using GNU/Linux for development
man-pages
Linux kernel and C library user-space interface documentation
NAME 名稱
accept - 在一個套接字上接收一個連接
SYNOPSIS 概述
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/socket.h>
int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
DESCRIPTION 描述
accept 函數用於基於連接的套接字 (SOCK_STREAM, SOCK_SEQPACKET 和 SOCK_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 注意
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 | |
沒有足夠內存. 這個錯誤一般來說意味着內存分配受套接字緩衝區所限, 而不是沒有系統內存. |
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 參見
[中文版維護人]
byeyear <love_my_love >
[中文版最新更新]
2002.01.27
《中國linux論壇man手冊頁翻譯計劃》:
http://cmpp.linuxforum.net
跋
本頁面中文版由中文 man 手冊頁計劃提供。
中文 man 手冊頁計劃:https://github.com/man-pages-zh/manpages-zh
中文 man 手冊頁計劃:https://github.com/man-pages-zh/manpages-zh
REFERENCED BY
sctp(7), bind(2), connect(2), getpeername(2), getsockname(2), getsockopt(2), listen(2), recv(2), select(2), select_tut(2), socket(2), socketcall(2), getaddrinfo(3), gethostbyname(3), getnameinfo(3), capabilities(7), ddp(7), ip(7), signal(7), sock_diag(7), socket(7), tcp(7), unix(7), socket-event(7), lpd(8), send(2), socket(1), msocket(2viewos)