accept() - Unix,Linux 系統呼叫 - 技術教學
Tutorials Point


  Unix 初學者教程
  Unix Shell 程式設計
  高階 Unix
  Unix 有用參考資料
  Unix 有用資源
  精選閱讀

版權所有 © 2014 tutorialspoint



  首頁     參考資料     討論論壇     關於 TP  

accept() - Unix,Linux 系統呼叫


previous next AddThis Social Bookmark Button

廣告

名稱

accept - 接受套接字上的連線

概要

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

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

描述

accept() 系統呼叫用於基於連線的套接字型別(SOCK_STREAMSOCK_SEQPACKET)。它從掛起的連線佇列中提取第一個連線請求,建立一個新的已連線套接字,並返回一個引用該套接字的新檔案描述符。新建立的套接字不是處於監聽狀態。原始套接字 sockfd不受此呼叫的影響。

引數 sockfd是一個使用socket(2)建立的套接字,使用bind(2)繫結到本地地址,並在listen(2)之後監聽連線。

引數 addr是指向sockaddr結構的指標。此結構中填充了對等套接字的地址,如通訊層所知。返回的addr地址的確切格式由套接字的地址族決定(參見socket(2)和相應的協議手冊頁)。

addrlen引數是一個值結果引數:它最初應包含addr指向的結構的大小;返回時,它將包含返回地址的實際長度(以位元組為單位)。當addr為NULL時,不會填充任何內容。

如果佇列中沒有掛起的連線,並且套接字未標記為非阻塞,則accept() 將阻塞呼叫者,直到出現連線。如果套接字標記為非阻塞且佇列中沒有掛起的連線,則accept()將失敗並返回錯誤 EAGAIN。

為了接收套接字上的傳入連線通知,可以使用select(2)或poll(2)。當嘗試新的連線時,將傳送可讀事件,然後可以呼叫accept()來獲取該連線的套接字。或者,可以將套接字設定為在套接字上發生活動時傳遞SIGIO;有關詳細資訊,請參見socket(7)。

對於某些需要顯式確認的協議(例如 DECNet),accept() 可以被認為只是將下一個連線請求出隊,而並不意味著確認。確認可以透過對新檔案描述符的正常讀或寫來隱含,拒絕可以透過關閉新套接字來隱含。目前只有 DECNet 在 Linux 上具有這些語義。

註釋

在傳遞SIGIOselect(2)或poll(2)返回可讀事件後,並不總是有連線等待,因為連線可能在呼叫accept()之前被非同步網路錯誤或其他執行緒刪除。如果發生這種情況,則呼叫將阻塞,等待下一個連線到達。

為確保accept()永不阻塞,傳遞的套接字sockfd需要設定O_NONBLOCK標誌(參見socket(7))。

返回值

成功時,accept()返回一個非負整數,它是已接受套接字的描述符。出錯時,返回 -1,並相應設定errno

錯誤處理

Linux accept()將新套接字上已掛起的網路錯誤作為accept()的錯誤程式碼傳遞。此行為與其他 BSD 套接字實現不同。為了可靠地操作,應用程式應在accept()之後檢測為協議定義的網路錯誤,並像EAGAIN一樣透過重試來處理它們。對於 TCP/IP,這些是ENETDOWNEPROTOENOPROTOOPTEHOSTDOWNENONETEHOSTUNREACHEOPNOTSUPPENETUNREACH

錯誤

如果出現以下情況,accept()將失敗:

標籤描述
EAGAINEWOULDBLOCK套接字標記為非阻塞,並且沒有連線可以接受。
EBADF 描述符無效。
ECONNABORTED 連線已中止。
EINTR 系統呼叫被在有效連線到達之前捕獲的訊號中斷。
EINVAL 套接字未監聽連線,或addrlen無效(例如,為負數)。
EMFILE 已達到開啟檔案描述符的每個程序限制。
ENFILE 已達到開啟檔案的系統限制總數。
ENOTSOCK 描述符引用的是檔案,而不是套接字。
EOPNOTSUPP 引用的套接字不是SOCK_STREAM型別。

如果出現以下情況,accept()可能會失敗:

標籤描述
EFAULT addr引數不在使用者地址空間的可寫部分。
ENOBUFS、ENOMEM 可用記憶體不足。這通常意味著記憶體分配受套接字緩衝區限制,而不是系統記憶體的限制。
EPROTO 協議錯誤。

如果出現以下情況,Linux accept()可能會失敗:

標籤描述
EPERM 防火牆規則禁止連線。

此外,新套接字的網路錯誤以及協議定義的網路錯誤可能會被返回。各種 Linux 核心可能會返回其他錯誤,例如ENOSRESOCKTNOSUPPORTEPROTONOSUPPORTETIMEDOUT。在跟蹤期間可能會看到值ERESTARTSYS

符合標準

SVr4、4.4BSD(accept() 首次出現在 4.2BSD 中)。

註釋

accept()的第三個引數最初宣告為“int *”(在 libc4 和 libc5 以及許多其他系統(如 4.x BSD、SunOS 4、SGI)下都是如此);POSIX.1g 草案標準希望將其更改為“size_t *”,這就是 SunOS 5 的情況。後來的 POSIX 草案使用“socklen_t *”,Single Unix Specification 和 glibc2 也是如此。

參見



previous next Printer Friendly

廣告


  

廣告



廣告