【问题标题】:bind socket to network interface将套接字绑定到网络接口
【发布时间】:2013-01-06 20:11:00
【问题描述】:

如何将套接字绑定到特定的网络接口?我尝试在服务器端使用setsockopt,但客户端仍然可以通过 eth0 和 lo 接口访问服务。

我可以通过使用serv_addr.sin_addr.s_addr 设置特定的IP 地址来实现这一点。

但我怀疑我们可以仅使用setsockopt 绑定到接口(无需提及 IP 地址)。

【问题讨论】:

    标签: c linux sockets


    【解决方案1】:

    你能做到的唯一方法就是你提到的 -

    通过使用serv_addr.sin_addr.s_addr设置特定的IP地址

    如果不知道要绑定的地址,你就无法做到这一点。

    如果需要,您可以使用ioctls 来确定当前的 IP 地址,尽管现在可能有更聪明的方法来做到这一点 - 我最近在现代 Linux 发行版中没有做太多。

    【讨论】:

    • 谢谢乔。我可以知道 setockopt 与 SO_BINDTODEVICE 的用法吗?
    【解决方案2】:

    您可以通过设置SO_BINDTODEVICE 套接字选项绑定到特定接口。

    struct ifreq ifr;
    
    memset(&ifr, 0, sizeof(ifr));
    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "eth0");
    if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) < 0) {
        ... error handling ...
    }
    

    警告您必须是 root 并且拥有CAP_NET_RAW 功能才能使用此选项。

    第二种方法是您可以使用getifaddrs() 解析绑定到接口的IP 地址。

    点击后面的链接查看综合示例。

    【讨论】:

    • 我有一个新问题,使用你的方法,eth0和eth1是否有相同的IP地址?
    【解决方案3】:

    也许有人会觉得它有用,所以我分享对我有用的解决方案(Linux、C++):

    uint32_t interfaceIndex = if_nametoindex(interfaceName);
    

    其中“interfaceName”是我们要绑定的接口的名称,例如“eth0”(参见:https://linux.die.net/man/3/if_nametoindex)。 现在我们可以通过“sin6_scope_id”在套接字地址结构中指定这个接口(如果我们使用 IPv6):

    struct sockaddr_in6 socketAddress;
    socketAddress.sin6_scope_id = interfaceIndex;
    

    现在我们可以像往常一样通过“绑定”将套接字绑定到接口。

    【讨论】:

      猜你喜欢
      • 2016-01-15
      • 1970-01-01
      • 2019-09-05
      • 1970-01-01
      • 2020-11-06
      • 1970-01-01
      • 2016-10-23
      • 1970-01-01
      • 2017-02-08
      相关资源
      最近更新 更多