我需要找到套接字使用的特定接口,以便我可以使用sysfs
文件(/sys/class/net/<IF>/statistics/etc
)保留它的统计信息。
我在下面的测试代码中尝试了两种不同的方法,但都失败了。第一个连接到远程服务器,并将ioctl
与SIOCGIFNAME
一起使用,但由于没有这样的设备而失败了#39;第二个使用带有getsockopt
的{{1}},但这又失败了(它将名称长度设置为0)。
有关这些失败原因或如何获取I / F名称的任何想法?在编译之后,将测试代码运行为SO_BINDTODEVICE
,其中test "a.b.c.d"
是正在侦听端口80的任何IPV4地址。请注意,我已经在Centos 7上编译了这个,但是没有似乎在a.b.c.d
中有IFNAMSZ
,因此您可能需要注释掉<net/if.h>
行才能在其他系统上进行编译。
感谢。
修改
我发现这实际上是How can I get the interface name/index associated with a TCP socket?的欺骗,所以我应该删除它。 (仅)其中一个答案是正确的(https://stackoverflow.com/a/37987807/785194) - 使用#define IFNAMSZ
获取您的本地IP地址,然后在getsockname
返回的列表中查找此地址。
关于套接字本质上是动态的一般问题(在下面提到,在另一个问题中多次提到):不太相关。我检查了内核源代码,套接字有一个接口索引和接口名称,API包含至少三种获取当前名称的方法,以及从索引中查找名称的其他例程,反之亦然。但是,索引是somtimes零,这是无效的,这就是下面的getifaddrs
版本失败的原因。不知道getsockopt
失败的原因。
ioctl
答案 0 :(得分:1)
TCP(和UDP)套接字未绑定到接口,因此实际上无法回答此查询。现在一般是正确的,给定套接字最终会根据对等端点的地址将数据包传递到特定接口,但是在套接字中没有编码。这是一个动态制定的路由决策。
例如,假设您正在与不直接位于本地LAN上的远程对等方进行通信。并且假设您通过eth0将默认网关配置为192.168.2.1。没有什么可以阻止你通过eth1配置第二个网关,比如192.168.3.1,然后关闭eth0。只要新网关也可以到达远程IP,现在可以使用eth1到达目的地,并且您的会话应该不间断地继续。
因此,如果您需要此信息,您需要从路由条目中推断出它(但要意识到它不能保证是静态的,即使在实践中它可能也是如此)。您可以从getpeername(2)
获取同伴的地址。然后,您可以检查可用的路线,以确定哪一条路线可以到达那里。
为此,您可以自己解析和解释/proc/net/route
,或者您可以只询问ip
命令。例如,我到(任意)ibm.com地址的路由通过我的eth0接口,并将套接字连接到那里,我的本地地址将是192.168.0.102(应该与连接套接字上的getsockname(2)
匹配):
$ ip route get 129.42.38.1
129.42.38.1 via 192.168.0.1 dev eth0 src 192.168.0.102
cache