accept函数详解

您所在的位置:网站首页 codesys随机数 accept函数详解

accept函数详解

2023-03-27 09:23| 来源: 网络整理| 查看: 265

       既然服务端已经很虔诚了,很真诚了,处于倾听状态,那么该是去尝试接受客户端请求的时候了,别只顾着倾听,不去接纳别人。

       接纳客户端请求的函数是accept, 我们先来看看函数的原型:

WINSOCK_API_LINKAGE SOCKET WSAAPI accept( SOCKET s, struct sockaddr FAR * addr, int FAR * addrlen );

        函数的第一个参数用来标识服务端套接字(也就是listen函数中设置为监听状态的套接字),第二个参数是用来保存客户端套接字对应的“地方”(包括客户端IP和端口信息等), 第三个参数是“地方”的占地大小。返回值对应客户端套接字标识。

 

        实际上是这样的: accept函数指定服务端去接受客户端的连接,接收后,返回了客户端套接字的标识,且获得了客户端套接字的“地方”(包括客户端IP和端口信息等)。

 

       accept函数非常地痴情,痴心不改:

       如果没有客户端套接字去请求,它便会在那里一直痴痴地等下去,直到永远(注意, 此处讨论的是阻塞式的socket.  如果是非阻塞式的socket, 那么accept函数就没那么痴情了, 而是会立即返回, 并意犹未尽地对未来的客户端扔下一句话: 我等了你, 你不来, 那就算了, 我懒得鸟你)。

 

        来看看accpt函数的用法:

        unsigned int sockConn = accept(sockSrv,(SOCKADDR*)&addrClient, &len);

 

        要睡觉了。睡觉之前,最后来看看linux中的accept:

ubuntu@VM-0-15-ubuntu:~$ man accept ACCEPT(2) Linux Programmer's Manual ACCEPT(2) NAME accept, accept4 - accept a connection on a socket SYNOPSIS #include /* See NOTES */ #include int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); #define _GNU_SOURCE /* See feature_test_macros(7) */ #include 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 cre[m ated socket is not in the listening state. The original socket sockfd is unaffected by this call. 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). 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 deter[m mined 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. 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. 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. 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 connec[m tions are present on the queue, accept() fails with the error EAGAIN or 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. 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. If flags is 0, then accept4() is the same as accept(). The following values can be bitwise ORed in flags to obtain different behavior: 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_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. 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. 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 applica[m tion 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. 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. EBADF The descriptor is invalid. ECONNABORTED A connection has been aborted. EFAULT The addr argument is not in a writable part of the user address space. EINTR The system call was interrupted by a signal that was caught before a valid connection arrived; see signal(7). EINVAL Socket is not listening for connections, or addrlen is invalid (e.g., is negative). EINVAL (accept4()) invalid value in flags. ......

         

          睡觉。

 

 



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3