如何指定在Linux中使用哪个接口

是否有可能绑定一个udp套接字到一个特定的接口,所以它通过该接口发送数据? 我有一个应用程序使用多个Udp套接字来发送数据,它运行在具有多个接口的机器上。 我知道可以通过使用下面的代码来指定接口名称:

int UdpSocket::open(const char *interface) { send_fd_ = ::socket(AF_INET, SOCK_DGRAM, 0); if (send_fd_ < 0) { perror("socket"); return -1; } int val = 1; int rc = ::setsockopt(send_fd_, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); if (rc < 0) { perror("sesockopt"); close(); return -1; } unsigned char ttl = 16; rc = ::setsockopt(send_fd_, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)); if (rc < 0) { perror("sesockopt_ttl"); close(); return -1; } if (interface != NULL) { struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), interface); rc = ::setsockopt(send_fd_, SOL_SOCKET, SO_BINDTODEVICE, (void*)&ifr, sizeof(ifr)); if (rc < 0) { perror("sesockopt"); close(); return -1; } } const int flags = ::fcntl(send_fd_, F_GETFL, 0); ::fcntl(send_fd_, F_SETFL, flags | O_NONBLOCK); return 0; } 

但是这要求应用程序以root权限运行,否则会抛出错误,提示“操作不允许”。

Solutions Collecting From Web of "如何指定在Linux中使用哪个接口"

最简单,也是最为理智的方法是添加匹配您的多播目的地的route

 ~# route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0 

因为OS网络堆栈根据路由表选择组播报文的出接口。 这也适用于监听 – 你只是绑定到组地址,内核会为你选择正确的接口。 你仍然必须像往常一样加入组。

从手册:

SO_BINDTODEVICE

将此套接字绑定到特定设备(如“eth0”),如传递的接口名称中所指定的那样。 如果名称为空字符串或选项长度为零,则将删除套接字设备绑定。 传递的选项是一个可变长度的以Null结尾的接口名称字符串,其最大大小为IFNAMSIZ。 如果一个套接字绑定到一个接口,那么只有从该特定接口接收到的数据包才被套接字处理。 请注意,这只适用于某些套接字类型,特别是AF_INET套接字。 它不支持数据包套接字(在那里使用普通绑定(2))。

这意味着你必须从自己的名字获得接口,可能使用getifaddrs,然后绑定到该地址。