网络编程0x04 Listen函数

网络编程0x04 Listen函数

文章目录

    • 网络编程0x04 Listen函数
      • 1.套接字分类
      • 2. listen函数
      • 3. 监听过程

1.套接字分类

TCP socket分两种:

  • 监听socket
  • 传输socket

监听socket:负责处理网络上来的连接请求(客户端的SYN包到达便是连接请求来了)

传输socket:负责在网络上的两个端点之间传输TCP数据

未决socket(pending socket): 就是某客户端的SYN包到达,内核为这个SYN包对应的TCP请求生成一个socket,但是此时三次握手并没有完成,这样的socket就是pending socket,是未决连接,没有经过三次握手认证的tcp连接。

已建立连接的socket(established socket):TCP服务器利用三次握手完成对客户端的简单认证之后,未决socket就变成已连接socket,后续可以用这个socket传输数据。

内核为每个tcp服务器维护两个socket队列:未决socket队列和已建立连接的socket队列

网络编程0x04 Listen函数_第1张图片

2. listen函数

listen函数用在服务器程序中,在进行bind函数之后,调用listen()将sockfd所引用的套接字标记为被动套接字,即,该套接字将用于使用accept接受传入的连接请求。

#include           /* See NOTES */
#include 

int listen(int sockfd, int backlog);

DESCRIPTION
       listen() marks the socket referred to by sockfd as a passive socket, that is, as a socket that will be used to accept incoming connection 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 request arrives when the queue is full, the client may receive an error with an indication of ECONNREFUSED or, if the underlying protocol supports retransmission, the request may be ignored so that a later reattempt at  connection succeeds.

RETURN VALUE
       On success, zero is returned.  On error, -1 is returned, and errno is set appropriately.

在TCP服务器端创建socket完毕,调用listen函数的时候,系统底层发生了以下动作:

  1. 将刚才创建的(fd所标示的)socket转换为此TCP服务器的监听socket,让此socket进入监听请求模式,此socket的tcp状态由CLOSE转至LISTEN.
  2. 内核为此监听socket所对应的tcp服务器建立一个未决socket队列和一个已建立连接socket队列, backlog这个参数用来决定未决socket队列的长度,有个映射关系,0表示长度可以无限大.

3. 监听过程

监听socket收到某客户端的SYN包,第一次握手完成.

然后内核为此SYN请求生成一个pending socket,例如图中的socket5,标记状态为SYN_RECV,并且将socket5加入相应的pending socket队列,并且服务器发出ACK和SYN,第二次握手完成。

后续针对此socket5有两种可能

第一种可能

过会儿客户端响应了服务器的SYN(第三个ACK到达),第三次握手结束。内核触发accept函数执行,将socket5状态标记为ESTABLISHED,并且将此socket5由pending socket queue移至establishedsocket queue
网络编程0x04 Listen函数_第2张图片

第二种可能

客户端的最后一个ACK一直没有到来,过很久,图中的socket5超时被移除
网络编程0x04 Listen函数_第3张图片

针对此listen,有两个极限情况导致的拒绝服务情况需要考虑:

backlog设置过小,pending socket队列已满,此时客户端调用connect发送SYN分节给服务器端请求连接,服务端会忽略此SYN包,客户端收不到SYN的ACK,会触发SYN超时,这个超时时间比较长,重发SYN,导致客户端长时间连接不上。

端请求连接,服务端会忽略此SYN包,客户端收不到SYN的ACK,会触发SYN超时,这个超时时间比较长,重发SYN,导致客户端长时间连接不上。

backlog设置为0或者过大,只要收到SYN包,就会在pending socket队列中增加节点,这个容易导致物理内存耗尽. Syn flood就是攻击pending socket队列的

你可能感兴趣的:(网络编程)