Linux 将套接字绑定到网络接口
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14478167/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
bind socket to network interface
提问by user2003595
How can I bind a socket to a particular network interface? I tried using setsockopt
on server side, but the clients can still access the service through both eth0 and lo interfaces.
如何将套接字绑定到特定的网络接口?我尝试setsockopt
在服务器端使用,但客户端仍然可以通过 eth0 和 lo 接口访问服务。
I can achieve this by setting the particular IP address using serv_addr.sin_addr.s_addr
.
我可以通过使用 serv_addr.sin_addr.s_addr
.
But I suspect that we can bind to an interface using only setsockopt
(without mentioning the IP address).
但我怀疑我们可以只使用setsockopt
(不提及 IP 地址)绑定到接口。
回答by Joe
The only way you can do it is as you mention -
你能做到的唯一方法就是你提到的——
by setting the particular IP address using
serv_addr.sin_addr.s_addr
通过使用设置特定的 IP 地址
serv_addr.sin_addr.s_addr
You can't do it without knowing the address to bind to.
如果不知道要绑定到的地址,您就无法做到这一点。
You can use ioctl
s to determine the current IP address if you need, though there may be a cleverer way to do this these days - I've not done much in modern Linux distros lately.
ioctl
如果需要,您可以使用s 来确定当前的 IP 地址,尽管现在可能有更聪明的方法来做到这一点 - 我最近在现代 Linux 发行版中没有做太多事情。
回答by Davide Berra
You can bind to a specific interface by setting SO_BINDTODEVICE
socket option.
您可以通过设置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 ...
}
Warning: You have to be root and have the CAP_NET_RAW
capability in order to use this option.
警告:您必须是 root 并且有CAP_NET_RAW
能力才能使用此选项。
The second method is that you can resolv IP address tied to an interface with getifaddrs().
第二种方法是您可以使用getifaddrs()解析绑定到接口的 IP 地址。
Follow the latter link for a comprehensive example.
按照后一个链接查看综合示例。
回答by stó? z powy?amywanymi nogami
Maybe someone will find it useful, so I am sharing the solution that worked for me (Linux, C++):
也许有人会发现它很有用,所以我分享了对我有用的解决方案(Linux、C++):
uint32_t interfaceIndex = if_nametoindex(interfaceName);
Where "interfaceName" is the name of the interface we want to bind to, e.g. "eth0" (see: https://linux.die.net/man/3/if_nametoindex). Now we can specify this interface in the socket address structure via "sin6_scope_id" (in case we use IPv6):
其中“interfaceName”是我们想要绑定的接口的名称,例如“eth0”(参见:https: //linux.die.net/man/3/if_nametoindex)。现在我们可以通过“sin6_scope_id”在套接字地址结构中指定这个接口(如果我们使用IPv6):
struct sockaddr_in6 socketAddress;
socketAddress.sin6_scope_id = interfaceIndex;
Now we can bind the socket to the interface via "bind" as usual.
现在我们可以像往常一样通过“绑定”将套接字绑定到接口。