Tcp “当我们说”时会发生什么;听一个端口;?

Tcp “当我们说”时会发生什么;听一个端口;?,tcp,network-programming,port,Tcp,Network Programming,Port,启动服务器应用程序时,我们总是需要指定它侦听的端口号。但这种“倾听机制”是如何在幕后实现的呢 我现在的想象是这样的: 操作系统将端口号与某个缓冲区相关联。服务器应用程序的职责是监视此缓冲区。如果此缓冲区中没有数据,服务器应用程序的侦听操作将阻塞应用程序 当一些数据从线路上到达时,操作系统将知道这一点,然后检查数据并查看其是否针对此端口号。然后它将填充相应的缓冲区。然后操作系统将通知被阻止的服务器应用程序,服务器应用程序将获取数据并继续运行 问题是: 如果上述情况正确,操作系统如何知道有来自有线

启动服务器应用程序时,我们总是需要指定它侦听的端口号。但这种“倾听机制”是如何在幕后实现的呢

我现在的想象是这样的:

操作系统将端口号与某个缓冲区相关联。服务器应用程序的职责是监视此缓冲区。如果此缓冲区中没有数据,服务器应用程序的侦听操作将阻塞应用程序

当一些数据从线路上到达时,操作系统将知道这一点,然后检查数据并查看其是否针对此端口号。然后它将填充相应的缓冲区。然后操作系统将通知被阻止的服务器应用程序,服务器应用程序将获取数据并继续运行

问题是:

  • 如果上述情况正确,操作系统如何知道有来自有线的数据?这不可能是繁忙的投票。它是某种基于中断的机制吗

  • 如果到达的数据太多,缓冲区不够大,是否会发生数据丢失

  • “侦听端口”操作真的是阻塞操作吗

非常感谢

  • 除了阻塞部分外,您的描述基本正确。操作系统通常使用中断来处理I/O事件,如到达的网络数据包,因此无需阻塞
  • 是的,如果同时发生了太多的连接尝试,有些会被反弹。调用
    listen
    或其等效项时,将指定到队列的连接数
  • 不,不是。当连接到达时,操作系统会在控制套接字上引发事件。您可以在等待此事件时选择阻塞,也可以使用一些非阻塞(
    select
    poll/epoll
    )或异步(重叠I/O、完成端口)机制
  • 典型的TCP服务器调用序列是

    socket() -> bind()-> listen() -> accept() -> read()/write() -> close()
    
    socket
    函数创建的套接字假定为活动套接字(将发出
    connect()
    )<代码>侦听()函数将未连接的套接字转换为被动套接字。这意味着内核应该开始接受传入的连接请求。
    listen()
    函数的第二个参数指定给定侦听套接字的总队列长度,该套接字包含两个队列- (1) 完成连接队列-已完成连接的3路握手 (2) 连接队列不完整-从客户端接收到SYN,正在等待完成3路TCP握手

    最后,TCP服务器调用
    accept()
    ,从已完成连接队列的前端返回下一个已完成连接。如果accept()成功,它将返回一个新的套接字描述符,该描述符引用客户端和服务器之间的TCP连接

    现在回答你的问题 *操作系统内核中的网络堆栈读取每个传入的IP数据包,根据其TCP/IP报头字段对数据包进行分类。IP数据包在线到达时,由以太网驱动程序作为中断提供服务,然后内核模式TCP/IP堆栈接管

    • 关于数据,如果您指的是SYN数据包,Posix.1g可以选择忽略新传入的SYN,或者在连接队列已满时向客户端发送RST。在三次握手完成后,但在服务器调用
      accept
      之前到达的数据应由服务器TCP排队,排队的大小不超过所连接套接字的接收缓冲区的大小

    • listen()

    有关TCP协议的更多详细信息,请参阅-握手、排序和确认以实现可靠传输

    这提供了有关TCP/IP Unix网络编程的非常详细的信息,可以提供有关此主题的更多见解

    如果上面的场景是正确的,操作系统如何知道有数据从有线到达?它不能是一个繁忙的池。它是某种基于中断的机制吗

    硬件通过发送中断通知操作系统,硬件中断导致事件处理程序运行

    如果到达的数据太多,缓冲区不够大,是否会发生数据丢失

    是的,但是TCP使用窗口机制。操作系统告诉另一端它有多少缓冲区,它可以动态地这样做。因此,它可能以“我有4k缓冲区”开始。2k到达后,另一端可以再发送2k,但我们可以确认前2k。如果另一端发送的信息太多,我们的操作系统会很快丢弃它。它还将告诉它减速,并重新承认它已经得到了什么。当缓冲区空闲时,我们可以告诉另一端继续。它将重新发送我们尚未确认的内容。当使用TCP时,操作系统会为我们完成所有这些,但不会为UDP

    “侦听端口”操作真的是阻塞操作吗

    是和否。它在完成之前不会返回,但没有多少事情要做: Listen几乎什么都不做,只是给操作系统写了个便条。“如果有人试图连接到该端口,则由我来处理”。等待连接的是accept。并接受can阻塞(以及读/写/…)

    操作系统不需要这么早就分配任何缓冲区。 Listen将一些元数据写入OS表。 传入的连接使用下一个连接处理缓冲区。
    稍后的数据进入并使用数据缓冲区,不需要为每个连接分配数据缓冲区。一个连接上的大量挂起数据可能会导致其他连接上的可用缓冲区减少。您的操作系统可能有使事情公平的策略和机制

    虽然其他答案似乎能正确地解释问题,但让我给出一个更直接的答案:你的想象是错误的

    应用程序没有缓冲区