gpt4 book ai didi

c - 为什么单独的 getaddrinfo-like() + connect() 没有重构为(理论上的)connect_by_name()?

转载 作者:太空宇宙 更新时间:2023-11-04 02:20:01 25 4
gpt4 key购买 nike

我见过的大多数应用程序都使用 TCP,大致执行以下操作来连接到远程主机:

  1. 从配置/用户输入(文本)中获取主机名(或地址)
  2. 要么将主机名解析为地址并添加端口,要么使用 getaddrinfo()
  3. 从上面填写远程地址之一的sockaddr_*结构
  4. 使用 connect() 将套接字连接到远程主机。
  5. 如果失败,可能转到 (3) 并重试 - 或者只是提示错误

(2) 在库存库实现中是阻塞的,而 (4) 似乎是最常见的非阻塞,这似乎为许多类似但不同的代码提供了空间,这些代码用于异步连接通过其主机名到远程主机。

所以问题是:没有像下面这样的额外单个调用的充分理由是什么:

int sockfd = connect_by_name(const char *hostname, const char *servicename)

?

我可以想出三个:

  • 具有历史意义:因为 API 就是这样
  • 为地址选择/连接重试提供自定义的每个应用程序策略机制:这似乎有点肤浅,因为对于常见情况(“给我一个与远程主机通话的管道”),底层操作系统应该更清楚<
  • 向用户提供有关所涉及的确切步骤(“名称解析”与“连接尝试”)的视觉反馈:这似乎很重要,查找+连接尝试可能需要时间

他们中只有最后一个似乎足够引人注目,可以为每个客户端应用程序重写解析/连接代码(而不是至少拥有和使用一个广泛使用的库,除了现有的语义之外,还可以实现 connect_by_name() sockets API),所以肯定还有更多我想念的原因?

(问题背后的原因之一是这种 API 似乎有助于移植到 IPv6,以及可能显着地移植到其他流传输协议(protocol))

或者,也许存在这样的库,但我的 google-fu 失败了?

(已编辑:将定义更正为看起来应该看起来,感谢 LnxPrgr3)

最佳答案

在标准库的约束下实现这样一个具有非阻塞特性的 API(至关重要的是,标准库不应该启动它自己的线程或进程来异步工作)将是有问题的。

过程中的名称查找和连接部分都需要等待远程响应。如果其中任何一个都不阻塞,则需要一种方法来执行异步工作并将套接字状态的变化发送给调用应用程序。 connect 之所以能够做到这一点,是因为 connect 调用的工作是在内核中完成的,并且内核可以在连接完成时将套接字标记为可读。但是,名称查找不能能够做到这一点,因为名称查找的工作是在用户空间中完成的——并且没有启动一个新线程(这在标准库中是禁止的),给出该名称查找编写一种被唤醒以继续工作的方法是一个难题。

可以通过让您建议的调用返回两个 文件描述符来做到这一点 - 一个用于套接字本身,另一个告诉您“什么都不做 使用此文件描述符,除了定期检查它是否可读。如果此文件描述符变为可读,则调用 cbn_do_some_more_work(fd)”。这显然是一个相当平淡的 API!

通常的 UNIX 方法是提供一组简单、灵活的工具,处理一小组对象类型,可以组合这些对象类型以产生复杂的效果。这既适用于编程 API,也适用于标准 shell 工具。

关于c - 为什么单独的 getaddrinfo-like() + connect() 没有重构为(理论上的)connect_by_name()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1794426/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com