【问题标题】:Can bind() socket to remote address?可以绑定()套接字到远程地址吗?
【发布时间】:2017-04-27 23:20:46
【问题描述】:

通过下面的 C 代码快照,我了解到,bind() 调用绑定到listfd 的地址是运行该服务器程序的本地机器的逻辑地址。随后,服务器侦听同一台机器的listfd 套接字。

struct sockaddr_in serv_addr; 
listfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 
serv_addr.sin_port = htons(8000);
retval = bind(listfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listfd)

我在coursera学到了--- 也就是说,bind() 调用还允许您将套接字绑定到远程地址和端口。

我想明白这一点。

我的意思是, listfd = socket(AF_INET, SOCK_STREAM, 0); 提供该程序正在运行的程序进程(本地机器)的文件描述符。

我的问题:

如果 bind() 调用将此本地套接字 listfd 绑定到远程地址而不是 INADDR_ANY,那么实际上是哪台机器在监听?因为listfd 是运行该程序的本地机器的本地进程文件描述符表中的一个条目,并且此套接字listfd 正在绑定到远程机器IP 地址?我该如何解释?这在后台是如何工作的?

【问题讨论】:

  • 我怀疑 Coursera 的编辑不足。 “本地或远程地址”应简单地替换为“地址”。最接近“本地或远程”二分法的有意义的是“远程可见或本地可见”地址(如绑定到网络接口的地址与环回地址)。如果可以,请向 coursera 提交错误报告。
  • @Arkadiy Ah 远程可见,得到你

标签: c sockets bsd


【解决方案1】:

我同意 Coursera 的材料可能是错误的,或者至少会误导关于网络编程的入门级学习。

但是,我无法抑制迂腐的评论。可以(在 Linux 上)绑定到非本地 IP 地址。请参阅http://man7.org/linux/man-pages/man7/ip.7.html 的选项 IP_TRANSPARENT。不过,这可能与手头的问题几乎没有关系。我也很欣赏这个问题被标记为 bsd。

更重要的是,bind() 与倾听没有任何关系。它只是将 fd 与地址相关联。启用“监听”的是listen() 调用。可以bind() 用于传出连接的套接字。

【讨论】:

    【解决方案2】:

    您不能将bind() 发送到远程地址,至少不能在AF_INET 家族中。根据man page of bind,你会得到一个EADDRNOTAVAIL的错误,说你要绑定的地址不是本地的。

    编辑:bind() 可能适用于远程地址,但它肯定不适用于AF_INET 系列。请注意,还有更多。可能有一些家族确实支持绑定到远程地址,可能是一些集群协议。即使没有,bind() 也可以理论上在这些协议上工作,以防出现一些有意义的协议。

    Edit2:正如thuovila 指出的那样,实际上存在AF_INET 中的远程地址绑定有效的情况。即在绑定前设置IP_TRANSPARENT 套接字选项。 The man page of ip(7) 告诉我们:

       IP_TRANSPARENT (since Linux 2.6.24)
              Setting this boolean option enables transparent proxying on
              this socket.  This socket option allows the calling
              application to bind to a nonlocal IP address and operate both
              as a client and a server with the foreign address as the local
              endpoint.  NOTE: this requires that routing be set up in a way
              that packets going to the foreign address are routed through
              the TProxy box (i.e., the system hosting the application that
              employs the IP_TRANSPARENT socket option).  Enabling this
              socket option requires superuser privileges (the CAP_NET_ADMIN
              capability).
    
              TProxy redirection with the iptables TPROXY target also
              requires that this option be set on the redirected socket.
    

    因此,通过大量额外工作,您可以通过将本地和远程套接字与该套接字选项集绑定在一起来构建transparent proxy(如果我理解正确的话)。

    【讨论】:

    • 因为(如果我错了,请纠正我)使用本地地址,您实际上是在选择要监听的接口。所以远程地址没有意义。
    • 我不确定这有多准确。您可以拥有一个(物理或逻辑)网络接口和多个地址。 AFAIK,如果您选择其中一个地址进行侦听,您将不会侦听同一接口的其他地址。因此,手册页中的“接口”一词可能并不完全意味着“网络接口”。
    • @Jan 那么,我从哪里了解到这一点的来源是错误的信息?
    • 不知道,链接需要认证。不过请阅读我的编辑,bind 理论上可能适用于此,但我不知道有任何家庭支持它。
    猜你喜欢
    • 2013-05-25
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 2023-02-12
    相关资源
    最近更新 更多