accept 翻译

ACCEPT(2)                                     Linux Programmer's Manual                                     ACCEPT(2)

NAME
       accept, accept4 - accept a connection on a socket		/*在一个套接字上接收一个连接*/

SYNOPSIS
       #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>

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

       #define _GNU_SOURCE             /* See feature_test_macros(7) */
       #include <sys/socket.h>

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

DESCRIPTION
       The  accept()  system  call  is  used  with  connection-based  socket types (SOCK_STREAM, SOCK_SEQPACKET).  It extracts the first connection request on the queue of pending connections for the  listening  socket,  sockfd, creates a new connected socket, and returns a new file descriptor referring to that socket.  The newly created socket is not in the listening state. The original socket sockfd is unaffected by this call.
	   /*accept 函数是用于基于连接的套接字(SOCK_STREAM, SOCK_SEQPACKET)。它会选择连接等待队列中的第一个连接请求,然后创建一个新的连接套接字并且返回一个指向该套接字的文件描述符。新创建的套接字并不会处于监听状态,原来的套接字(accept 参数中的套接字描述符所指向的套接字)不会受到 accept 调用函数的影响(包括文件状态位标志等)*/
	   
       The argument sockfd is a socket that has been created with socket(2), bound to a local address  with  bind(2), and is listening for connections after a listen(2).
	   /*sockfd 参数是一个套接字,该套接字由 socket 函数创建、bind 函数绑定本地地址,并且最后由 listen 函数设置用于监听连接的套接字。*/
	     
       The argument addr is a pointer to a sockaddr structure. This structure is filled in with the address of the peer socket, as known to the communications layer. The exact format of the address returned addr is determined by the socket's address family (see socket(2) and the respective protocol man pages). When addr is NULL, nothing is filled in; in this case, addrlen is not used, and should also be NULL.
	   /*addr 参数是一个指向 sockaddr 结构体的指针。该结构体包含了对方 socket 的地址,也就是众所周知的网络层。addr 的准确格式取决于套接字的地址族(请参阅 socket(2) 和相应的协议手册页)。当 addr == NULL 时,accept 函数不会获取任何信息,这时 addrlen 参数就毫无意义了,那么最后一个参数也应该填 NULL*/

       The addrlen argument is a value-result argument: the caller must initialize it to contain the size (in  bytes) of the structure pointed to by addr; on return it will contain the actual size of the peer address.
	   /*addrlen 参数是一个值结果参数:调用者必须先初始化它,该参数用于储存 addr 指向结构体的大小(以字节为单位)。函数返回时,addrlen 将会把对方地址结构体的大小一并带回*/
	   	   
       The returned address is truncated if the buffer  provided is too small; in this case, addrlen will return a value greater than was supplied to the call.
	   /*如果提供的缓冲区太小,那么返回的地址将会被截断;这时,addrlen 将会返回一个大于给该调用提供的值*/

       If no pending connections are present on the queue, and the socket is  not  marked  as  nonblocking,  accept() blocks  the  caller until a connection is present.  If the socket is marked nonblocking and no pending connections are present on the queue, accept() fails with the error EAGAIN or EWOULDBLOCK.
	   /*如果当前队列中没有等待的连接,并且 socket 也没有标记为非阻塞时, accept 函数将会阻塞调用者直到有连接为止。如果 socket 被标记为非阻塞并且当前队列中没有等待的连接时,那么 accept 函数将会出错,错误代码为 EAGAIN 或 EWOULDBLOCK*/

       In order to be notified of incoming connections on a socket, you can use select(2) or poll(2). A readable event  will be delivered when a new connection is attempted and you may then call accept() to get a socket for that connection.  Alternatively, you can set the socket to deliver SIGIO when activity occurs on a socket; see socket(7) for details.
	   /*我们可以通过调用 select 函数或者 poll 函数来知道目前加入到连接队列的套接字。当一个新的请求尝试连接,并且此时我们调用 accept 函数创建了一个 socket ,这时我们就可以实现可读事件的传递了。当然了,我们也可以对 socket 进行设置,当 socket 有变化时立即发送 SIGIO 信号。具体细节参见 socket(7)*/

       For certain protocols which require an explicit confirmation, such as DECNet, accept() can be thought of as merely dequeuing the next connection request and not implying confirmation. Confirmation can be implied by a normal read or write on the new file descriptor, and rejection can be implied by closing the new socket. Currently only DECNet has these semantics on Linux.
	   /*对于某些需要显式确认的协议,例如 DECNet,accept 函数则可以看作仅仅从队列中取出下一个连接而不做确认。当在一个新的文件描述符上进行普通读写操作时暗含了确认,当关闭这个新的套接字时暗含了拒绝。目前在 Linux 上只有 DECNet 具有这些含义*/

       If flags is 0, then accept4() is the same as accept(). The following values can be bitwise ORed in flags to obtain different behavior:
	   /*如果 flag 参数为 0,则 accept4 函数和 accept 函数一样。以下值可以在标志中按位或运算以获得不同的行为。*/

       SOCK_NONBLOCK   Set the O_NONBLOCK file status flag on the new open file description. Using this flag saves extra calls to fcntl(2) to achieve the same result.
	   /*SOCK_NONBLOCK	在新的打开文件描述中设置 O_NONBLOCK(非阻塞)文件状态标志.使用此标志可以节省对 fcntl 的额外调用,以实现相同的结果*/

       SOCK_CLOEXEC    Set the close-on-exec (FD_CLOEXEC) flag on the new file descriptor. See the description of the O_CLOEXEC flag in open(2) for reasons why this may be useful.
	   /*SOCK_CLOEXEC	在新的打开文件描述中设置 close-on-exec (FD_CLOEXEC)文件状态标志.请参阅open 函数中 O_CLOEXEC 标志的说明了解设置该状态标志位的用处。*/	   

RETURN VALUE
		On  success, these system calls return a nonnegative integer that is a descriptor for the accepted socket. On error, -1 is returned, and errno is set appropriately.
		/*成功,这些系统调用会返回一个非负整数,它是接受套接字的描述符;失败返回 -1,错误代码保存在 errno 中*/

		Error handling Linux accept() (and accept4()) passes already-pending network errors on the new socket as an error  code  from accept(). This  behavior differs from other BSD socket implementations.  For reliable operation the application should detect the network errors defined for the protocol after accept() and treat them  like  EAGAIN  by retrying.   In the case of TCP/IP, these are ENETDOWN, EPROTO, ENOPROTOOPT, EHOSTDOWN, ENONET, EHOSTUNREACH, EOPNOTSUPP, and ENETUNREACH.
		/*Linux accept(and accept4) 的错误处理是通过双方所连接的网络上的新的套接字实现的,该套接字所传递的错误信息仅仅只是 accept 函数出错所产生的错误代码,也就是 errno 的值,该方法与其他 BSD 套接字的实现有所不同。为了实现可靠的操作,应用程序应该在 accept 函数之后检测由于协议定义所产生的网络错误,并可以像 EAGAIN 一样通过重试对待。在 TCP/IP 情况下包括: ENETDOWN, EPROTO, ENOPROTOOPT, EHOSTDOWN, ENONET, EHOSTUNREACH, EOPNOTSUPP, and ENETUNREACH*/

	ERRORS
       EAGAIN or EWOULDBLOCK The socket is marked nonblocking and no connections are present to be accepted. POSIX.1-2001  and POSIX.1-2008 allow either error to be returned for this case, and do not require these constants to have the same value, so a portable application should check for both possibilities.
	   /*EAGAIN or EWOULDBLOCK	套接字被标记为非阻塞,同时并不存在要接受的连接。POSIX.1-2001 和 POSIX.1-2008 允许为这种情况返回错误,并且不要求这些常量具有相同的值,因此可移植的应用程序应该检查两种可能性*/

       EBADF  The descriptor is invalid.
	   /*EBADF		描述符无效*/

       ECONNABORTED A connection has been aborted.
	   /*ECONNABORTED		连接已终止*/

       EFAULT The addr argument is not in a writable part of the user address space.
	   /*EFAULT				addr 参数不是用户地址空间的可写部分*/

       EINTR  The system call was interrupted by a signal that was caught before a valid connection arrived; see signal(7).
	   /*EINTR				系统调用被一个在有效连接到达之前捕获的信号中断*/

       EINVAL Socket is not listening for connections, or addrlen is invalid(e.g., is negative).
	   /*EINVAL				socket 并不是监听套接字,或者 addrlen 是无效的(例如,addrlen 是负值)*/

       EINVAL (accept4()) invalid value in flags.
	   /*EINVAL				accept4 函数无效的标志位设置*/

       EMFILE The per-process limit on the number of open file descriptors has been reached.
	   /*EMFILE				已达每个进程所能打开的文件描述符上限*/

       ENFILE The system-wide limit on the total number of open files has been reached.
	   /*ENFILE				已达到系统范围内打开文件总数的上限*/

       ENOBUFS, ENOMEM Not enough free memory. This often means that the memory allocation is limited by the socket buffer limits, not by the system memory.
	   /*ENOBUFS, ENOMEM	内存不足。这个错误一般来说意味着内存分配受套接字缓冲区所限, 而不是没有系统内存*/

       ENOTSOCK The file descriptor sockfd does not refer to a socket.
	   /*ENOTSOCK			sockfd 参数不是一个套接字*/

       EOPNOTSUPP The referenced socket is not of type SOCK_STREAM.
	   /*EOPNOTSUPP			引用的套接字不是 SOCK_STREAM 类型*/

       EPROTO Protocol error.
	   /*EPROTO				协议错误*/

       In addition, Linux accept() may fail if:
	   /*此外,如果出现以下情况,Linux accept 函数也会出错*/

       EPERM  Firewall rules forbid connection.
	   /*EPERM				防护墙设置禁止连接*/

       In addition, network errors for the new socket and as defined for the protocol may be returned. Various Linux kernels  can return other errors such as ENOSR,  ESOCKTNOSUPPORT, EPROTONOSUPPORT, ETIMEDOUT. The value ERESTARTSYS may be seen during a trace.
	   /*此外,新套接字的网络错误以及协议中定义的错误也会被返回。不同的 Linux 内核也会返回一些其他问题,如:ENOSR,  ESOCKTNOSUPPORT, EPROTONOSUPPORT, ETIMEDOUT。一直追溯可以看到 ERESTARTSYS 的值*/

VERSIONS
       The accept4() system call is available starting with Linux 2.6.28; support in glibc is available starting with version 2.10.
	   /*accept4 系统调用函数从 Linux 2.6.28 版本才开始使用的;glibc 支持版本是从 2.10 开始提供*/

CONFORMING TO
       accept(): POSIX.1-2001, POSIX.1-2008, SVr4, 4.4BSD (accept() first appeared in 4.2BSD).
	   /*accept 函数第一次出现是在 4.2BSD 中*/

       accept4() is a nonstandard Linux extension.
	   /*accept4 函数是一个非标准的 Linux 扩展*/

       On Linux, the new socket returned by accept() does not inherit file status flags such as O_NONBLOCK and O_ASYNC from the listening socket. This behavior differs from the canonical BSD sockets implementation. Portable programs should not rely on inheritance or noninheritance of file status flags and always explicitly set all required flags on the socket returned from accept().
	   /*在 Linux 上,accept 函数返回的新套接字不会从监听套接字中继承文件状态标志,例如:O_NONBLOCK 和 O_ASYNC。这和规范的 BSD 套接字实现机制有所不同。可移植程序不应该依赖于文件状态的是否可继承,而是应当在 accept 函数返回时就将所有需求都在 socket 的相应标志位上设置好。
	   可移植程序不应该依赖于文件状态标志的继承或不继承,并且总是显式地设置从accept()返回的套接字上所有必需的标志。*/

NOTES
       POSIX.1-2001 does not require the inclusion of <sys/types.h>, and this header file is not required on Linux. However, some historical (BSD) implementations required this header file, and portable applications are probably wise to include it.
	   /*POSIX.1 不需要 <sys/types.h>头文件,但是由于历史原因(例如:BSD)就需要该头文件,所有还是加一下该头文件比较好*/
	 
       There may not always be a connection waiting after a SIGIO is delivered or select(2) or poll(2) return a readability  event because the connection might have been removed by an asynchronous network error or another thread before accept() is called.  If this happens, then the call will block waiting for the  next  connection to  arrive.   To ensure that accept() never blocks, the passed socket sockfd needs to have the O_NONBLOCK flag set (see socket(7)).
	   /*当接收到一个 SIGIO 信号或者 select、poll 函数返回读就绪时并不总是意味着有新的连接在等待,因为连接很可能在 accept 函数调用之前被一个异步网络错误或者另一个线程删除。如果发生这种情况, 那么调用将阻塞并等待下一个连接的到来。为确保 accept 永远不会阻塞,传递的套接字 sockfd 需要设置成 O_NONBLOCK 标志(参见 socket(7))*/

   The socklen_t type		/*socklen_t 类型*/
       The third argument of accept() was originally declared as an int * (and is that under libc4 and libc5  and  on many other systems like 4.x BSD, SunOS 4, SGI); a POSIX.1g draft standard wanted to change it into a size_t *, and that is what it is for SunOS 5.  Later POSIX drafts have socklen_t *, and so do the Single UNIX Specification and glibc2. Quoting Linus Torvalds:
	   /*函数 accept 的第三个参数原来被声明为 int * (在libc4 和 libc5 以及其他很多系统中, 比如 BSD 4.x, SunOS 4, SGI); POSIX.1g 草案试图将其改变为 size_t * 类型, SunOS 5  是这么做的。 后来的POSIX 草案和 Single Unix Specification 以及 glibc2 使用了 socklen_t *。引用 Linus Torvalds 一段话:*/

       "_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 说这是由于他们发现了自己的错误但又不好意思向大家伙儿承认,所以另外创造了一个新的数据类型。*/

EXAMPLE
       See bind(2).

SEE ALSO
       bind(2), connect(2), listen(2), select(2), socket(2), socket(7)

COLOPHON
       This page is part of release 4.04 of the Linux man-pages project.  A description of the  project,  information about reporting bugs, and the latest version of this page, can be found at http://www.kernel.org/doc/man-pages/.

Linux                                                 2015-12-28                                            ACCEPT(2)

猜你喜欢

转载自blog.csdn.net/wenfei11471/article/details/80084259