Linux 理解BSD接口

Linux 理解BSD接口,linux,networking,tcp,Linux,Networking,Tcp,我试图理解BSD套接字接口中的事件如何转换为TCP连接的状态。特别是,我试图了解连接过程accept()在服务器端返回的阶段 客户端发送SYN 服务器发送SYN+ACK 客户端发送ACK 连接完成后,accept()return在以下哪一个步骤中返回?accept返回。客户端发送ACK后,连接完成 accept为您提供一个可以进行通信的套接字。当然,你知道,在建立连接之前,你无法沟通。在握手之前无法建立连接 在客户确认之前返回是没有意义的。在初始SYN之后,他完全可能什么也不说。accept在连

我试图理解BSD套接字接口中的事件如何转换为TCP连接的状态。特别是,我试图了解连接过程
accept()
在服务器端返回的阶段

  • 客户端发送SYN
  • 服务器发送SYN+ACK
  • 客户端发送ACK

  • 连接完成后,
    accept()
    return在以下哪一个步骤中返回?

    accept
    返回。客户端发送ACK后,连接完成

    accept
    为您提供一个可以进行通信的套接字。当然,你知道,在建立连接之前,你无法沟通。在握手之前无法建立连接


    在客户确认之前返回是没有意义的。在初始SYN之后,他完全可能什么也不说。

    accept
    在连接完成后返回。客户端发送ACK后,连接完成

    accept
    为您提供一个可以进行通信的套接字。当然,你知道,在建立连接之前,你无法沟通。在握手之前无法建立连接


    在客户确认之前返回是没有意义的。在初始SYN之后,他完全可能什么也不说。

    内核中的TCP/IP堆栈代码通常[1]完全完成三方握手,而不需要任何用户空间代码的干预。您列出的三个步骤都发生在
    accept()
    返回之前。实际上,它们可能发生在调用
    accept()
    之前

    当您告诉堆栈在特定TCP端口上的连接使用
    listen()
    时,您传递了一个
    backlog
    参数,它告诉内核一次可以代表您的程序静默地接受多少个连接。当内核自动接受新的连接请求时,使用的就是这个队列,在您的程序开始处理它们之前,它们一直被保留。当调用
    accept()
    时,侦听积压队列中存在一个或多个连接时,所发生的只是从队列中删除最旧的连接并绑定到新套接字。[2]

    换句话说,如果您的程序调用
    listen(sd,5)
    ,然后进入一个无限不做任何事情的循环,这样它就永远不会调用
    accept()
    ,从客户端的角度来看,五个并发的客户端连接请求将成功。第六个连接请求将在第一个SYN数据包上暂停,直到拥有TCP端口的程序调用
    accept()
    或其他客户端之一断开其连接


    [1] 当然,防火墙和其他堆栈修改可以改变这种行为。这里我只谈论默认的BSD套接字堆栈行为


    [2] 如果在调用
    accept()
    时积压中没有等待的连接,则默认情况下它会阻塞,除非侦听器套接字设置为非阻塞,在这种情况下它返回-1,并且
    errno
    ewoolblock

    内核中的TCP/IP堆栈代码正常[1]完全完成三方握手,无需任何用户空间代码的干预。您列出的三个步骤都发生在
    accept()
    返回之前。实际上,它们可能发生在调用
    accept()
    之前

    当您告诉堆栈在特定TCP端口上的连接使用
    listen()
    时,您传递了一个
    backlog
    参数,它告诉内核一次可以代表您的程序静默地接受多少个连接。当内核自动接受新的连接请求时,使用的就是这个队列,在您的程序开始处理它们之前,它们一直被保留。当调用
    accept()
    时,侦听积压队列中存在一个或多个连接时,所发生的只是从队列中删除最旧的连接并绑定到新套接字。[2]

    换句话说,如果您的程序调用
    listen(sd,5)
    ,然后进入一个无限不做任何事情的循环,这样它就永远不会调用
    accept()
    ,从客户端的角度来看,五个并发的客户端连接请求将成功。第六个连接请求将在第一个SYN数据包上暂停,直到拥有TCP端口的程序调用
    accept()
    或其他客户端之一断开其连接


    [1] 当然,防火墙和其他堆栈修改可以改变这种行为。这里我只谈论默认的BSD套接字堆栈行为


    [2] 如果在调用
    accept()
    时未在待办事项列表中等待任何连接,则默认情况下它会阻塞,除非侦听器套接字设置为非阻塞,在这种情况下,它返回-1并且
    errno
    ewoolblock

    实际上,TCP允许(需要?需要重新检查RFC793)在收到SYN后立即调用用户界面,让服务器决定是继续握手,还是当场拒绝连接。BSD接口没有此用户界面(出于充分的理由,IMHO),并且该功能由数据包筛选器提供。Linux中BSD套接字的行为已随Linux 2.2而改变。accept()将在有完全连接的套接字时返回(而不是在连接完成时)。@ninjalj很好。实际上,有些实现允许您为accept(winsock)指定过滤器。BSD套接字不这样做IIRC。实际上,TCP允许(需要?需要重新检查RFC793)在收到SYN后调用用户界面,让服务器决定是继续握手,还是当场拒绝连接。BSD接口没有此用户界面(出于充分的理由,IMHO),并且该功能由数据包筛选器提供。BSD的行为