TCP的accept发生在三次握手的哪个阶段?
这些天在网上看到这样一个题目,据听说是腾讯的面试题:
TCP三次握手的过程,accept发生在三次握手的哪一个阶段?
答案是:accept过程发生在三次握手之后,三次握手完成后,客户端和服务器就建立了tcp连接并可以进行数据交互了。这时可以调用accept函数获得此连接。
也许这个图描述的更加清晰。
image有的网友评论说这个题目太简单了,也有人说腾讯不会出这么简单的问题,但是就tcp accept而言你又知道多少呢?
我们今天就学习下TCP Accept
POSIX Programmer's Manua对TCP Accept的说明
Accept函数的原型是:
int accept(int socket, struct sockaddr *restrict address,socklen_t *restrict address_len);
功能描述的:
The accept() function shall extract the first connection on the queue of pending connections, create a new socket with the same socket type protocol and address family as the specified socket, and allocate a new file descriptor for that socket.
意思就是:accept函数会从已经建立连接的队列中取出第一个连接,并创建一个新的socket,新的socket的类型和地址参数要和原来的那个指定的socket的地址一一样,并且还要为这个新的socket分配文件描述符。
POSIX Programmer's Manual 还说了这么两句话
The accepted socket cannot itself accept more connections. The original socket remains open and can accept more connections.
新建的这个socket自身是无法再接收连接了,但是最开始的那个socket仍然是处于开放状态,而且可以接收更多连接。
If the listen queue is empty of connection requests and O_NONBLOCK is not set on the file descriptor for the socket, accept() shall block until a connection is present. If the listen() queue is empty of connection requests and O_NONBLOCK is set on the file descriptor for the socket, accept() shall fail and set errno to [EAGAIN] or [EWOULDBLOCK].
意思就是:在连接的监听队列为空并且O_NONBLOCK 没有置位的情况下,accpet是阻塞的。如果监听队列为空,但是O_NONBLOCK 置位的情况下,accpet会立即返回。
TCP Accept总结
TCP Accept 是三次握手以后,Accept正确返回以后TCP Server 可以和Client的连接已建立并可以通信了
注意区分listen socket 和 accept socket。
socket分为两种,一种套接字正如accept的参数sockfd,它是listen socket,在调用listen函数之后,一个socket会从主动连接的套接字变为listen 套接字;而accept返回是一个连接套接字,它代表着一个网络已经存在的点对点连接。以后的数据交互就是基于这个连接socket ,而之前的那个listen socket可以继续工作,从而接收更多的连接。
Accept默认会阻塞进程,直到有一个客户连接建立后返回