ACCEPT
ACCEPT
章節(jié):Linux 程序員手冊 (2)更新:2010-09-10
到 易美翻譯 翻譯
名字
accept - 通過套接口接受一個(gè)連接概要
#include Esys/types.h> /* 參看 “注意小節(jié)” */ #include Esys/socket.h>int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);#define _GNU_SOURCE /* 參考 feature_test_macros(7) */ #include <sys/socket.h>int accept4(int sockfd, struct sockaddr *addr,socklen_t *addrlen, int flags);描述
accept() 系統(tǒng)調(diào)用應(yīng)用于可連接套接口類型 ( SOCK_STREAM, SOCK_SEQPACKET)。它取出在監(jiān)聽套接口 sockfd請求隊(duì)列里的第一個(gè)連接,新建一個(gè)已連接的套接口,并且返回一個(gè)引用該套接口新的文件描述符。新建的套接口不處于監(jiān)聽狀態(tài)。原始的套接口 sockfd 沒有受到影響。參數(shù) sockfd 是一個(gè)由 socket(2) 創(chuàng)建的套接口,通過 bind綁定到一個(gè)本地地址,并且在調(diào)用 listen(2)之后正處于監(jiān)聽之中。
參數(shù) addr 是指向一個(gè) sockaddr結(jié)構(gòu)的指針。這結(jié)構(gòu)體被填充為一個(gè)端套接口,又被稱為通信層。返回的地址結(jié)體 addr的額外的格式可以通過套接口地址族(參看 socket(2)和各自的協(xié)議手冊頁)來確定。當(dāng) addr 是 NULL 時(shí),沒有內(nèi)容被填充,此時(shí) addrlen不被使用,同時(shí)也可以是 NULL。
參數(shù) addrlen 是一個(gè)“值-返回”型參數(shù),調(diào)用者必須把它初始化為 addr指向的結(jié)構(gòu)的大小(字節(jié)數(shù)),返回時(shí),它指出端地址的實(shí)際大小。
如果提供的緩沖區(qū)太小,返回的地址將被截?cái)?#xff0c;此時(shí),addrlen 將返回一個(gè)比傳入更大的值。
如果隊(duì)列里沒有未處理的連接,并且套接口沒有標(biāo)記為不阻塞,accept()會阻塞當(dāng)前調(diào)用進(jìn)程直到有一個(gè)連接出現(xiàn)。如果沒有未處理的連接,同時(shí)套接口被標(biāo)記為不阻塞,accept() 返回EAGAIN 或 EWOULDBLOCK 錯(cuò)誤。
為了在一個(gè)套接口有連接時(shí)收到通知,你可以使用 select(2) 或 poll(2)。當(dāng)有連接時(shí),一個(gè)可讀事件被遞送。進(jìn)一步,你可以設(shè)置當(dāng)一個(gè)套接口可用時(shí),發(fā)送一個(gè)SIGIO,參看 socket(7)來詳細(xì)了解。
對于一些需要顯示驗(yàn)證的協(xié)議,比如說 DECNet,accept()只是從隊(duì)列里取出連接請求,并沒有執(zhí)行驗(yàn)證。驗(yàn)證將在下次對新建的文件描述符進(jìn)行正常的讀或?qū)憰r(shí)進(jìn)行,并且拒絕可以通過關(guān)閉那個(gè)新建的套接口來進(jìn)行。目前在Linux 中只有 DECNet 有如此語義。
flags 是 0,那么 accept4() 與 accept() 功能一樣。下面flags 的值可能通過位求或運(yùn)算來得到不同的行為:
SOCK_NONBLOCK返回值
成功時(shí),這個(gè)系統(tǒng)調(diào)用返回一個(gè)非負(fù)整數(shù)的文件描述符來代表接受的套接口。錯(cuò)誤時(shí),返回 -1,并把 errno設(shè)置為合適的值。錯(cuò)誤處理
在 Linux 里, accept() (和 accept4()) 把本屬于accept() 的但未處理的網(wǎng)絡(luò)錯(cuò)誤傳遞給新建的套接口。 這個(gè)行為不同于其它 BSD 的實(shí)現(xiàn)。 可靠的應(yīng)用應(yīng)該在調(diào)用 accept() 之后檢測相應(yīng)協(xié)議可能的網(wǎng)絡(luò)錯(cuò)誤,并且處理 EAGAIN 一樣重試一次。對于 TCP/IP來說,這些錯(cuò)誤有 ENETDOWN、 EPROTO、 ENOPROTOOPT、 EHOSTDOWN、 ENONET、 EHOSTUNREACH、 EOPNOTSUPP和 ENETUNREACH。錯(cuò)誤
EAGAIN 或 EWOULDBLOCK此外,Linux 下的 accept() 可能因如下原因失敗:
EPERM還有,新建套接口和協(xié)議相關(guān)的網(wǎng)絡(luò)錯(cuò)誤也可能被返回。多種 Linux 內(nèi)核還會返回諸如ENOSR、ESOCKTNOSUPPORT、EPROTONOSUPPORT、ETIMEDOUT的錯(cuò)誤。ERESTARTSYS 的值也可能需要關(guān)注。
版本
accept4() 系統(tǒng)調(diào)用從 Linux 2.6.28 開始支持,glibc 在版本 2.10 開始支持。遵循于
accept():POSIX.1-2001, SVr4, 4.4BSD, ( accept() 首次出現(xiàn)在4.2BSD)。accept4() 是非標(biāo)準(zhǔn) Linux 擴(kuò)展。
在 Linux 系統(tǒng)里,accept() 返回的新建的套接口 不會 繼承監(jiān)聽套接口的諸如O_NONBLOCK 和 O_ASYNC 這樣的文件狀態(tài)。這個(gè)行為與正規(guī)的 BSD套接口實(shí)現(xiàn)不一致。可移植的程序不應(yīng)該假設(shè)文件狀態(tài)是繼承或不繼承的,總是顯示地設(shè)置 accept()返回的套接口需要的標(biāo)記位。
注意
POSIX.1-2001 不要求包含 <sys/types.h>,并且這個(gè)頭文件在 Linux中也不要求。然而一些歷史(BSD)實(shí)現(xiàn)要求這個(gè)頭文件,可移植的應(yīng)用程序應(yīng)該包含這個(gè)文件。在 SIGIO 遞送之后,在 select(2) 或 poll(2) 返回但連接卻因?yàn)橐粋€(gè)異步網(wǎng)絡(luò)錯(cuò)誤而刪除之后,或在其它線程調(diào)用accept() 之前,不需要總是等待。如果這些事發(fā)生了,調(diào)用將被阻塞到一個(gè)新連接到來,為了讓accept() 絕不阻塞,傳入的 sockfd 需要設(shè)置 O_NONBLOCK 標(biāo)記(參看socket(7))。
socklen_t 類型
accept() 的第三個(gè)參數(shù)最初被聲明為 int* (在 libc4 和 libc5,以及一些諸如4.x BSD、SunOS4、SGI)。POSIX.1g 草案想把它改為 size_t *,這與SunOS 5是一樣的,接著 POSIX 草案提出了 socklen_t *,并且在 Single UnixSpecification 和 glibc2 也是如此。Linus Torvalds 曾說:“任何合理的庫都必須保證 socklen_t 與 int 有相同的長度。否則的話都會與 BSD 套接口不同。POSIX 最初把它定義 為 size_t ,而我(同時(shí)也希望其他人,但顯然不是太多)對他們表示強(qiáng)烈的不贊同。把它定義為 size_t將是完全地不兼容,尤其在 64 位系統(tǒng)里,size_t 很少跟 int 有相同的寬度。它 必須 與 int有相同的寬度,因?yàn)?BSD 接口是這樣的。無論如何,制定 POSIX 的人還是創(chuàng)造出 socklen_t了。他們最初不應(yīng)該去碰這個(gè)東西,但是一旦他們碰了,變會因?yàn)橐恍┥願(yuàn)W的原因提供一個(gè)命名的類型(可能有些人因?yàn)橹坝薇康男袨槎鴣G臉時(shí),就會靜悄悄地他們的行為換個(gè)名字)。”
示例
參考 bind(2)。參看
bind(2), connect(2), listen(2), select(2), socket(2), socket(7)
英文原版:http://man7.org/linux/man-pages/dir_all_alphabetic.html
總結(jié)
- 上一篇: UWP日渐式微!微软Windows商店还
- 下一篇: 比亚迪新能源销量国产第一 申请18.41