Manpages

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 [AT] 263.net >

[中 文 版 最 新 更 新 ]

2002.01.27

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

http://cmpp.linuxforum.net

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