listen系统调用在手册中的介绍:
int listen(int sockfd, int backlog);
listen() marks the socket referred to by sockfd as a passive socket, that is, as a socket that will be used to accept incoming con‐
nection requests using accept(2).
The sockfd argument is a file descriptor that refers to a socket of type SOCK_STREAM or SOCK_SEQPACKET.
The backlog argument defines the maximum length to which the queue of pending connections for sockfd may grow. If a connection re‐
quest arrives when the queue is full, the client may receive an error with an indication of ECONNREFUSED or, if the underlying proto‐
col supports retransmission, the request may be ignored so that a later reattempt at connection succeeds.
也就是listen会将sockfd标记为一个被动的socket,它将通过accept系统调用接受连接请求。其中,backlog参数指定了sockfd用于pending connection的队列的最大长度。(也就是说listen的具体实现中有队列?)
accept在手册中:
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 unaf‐
fected 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 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.
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 connections 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), poll(2), or epoll(7). 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.
总之,accept的第二三个参数是会在调用函数后被赋值的(所以传入的是指针)。accept会从sockfd的队列中拿出第一个连接请求,创建一个新的socket,并返回其fd。