正确的方法是将bind()绑定到要用于传出数据包的接口。由于您随后可以使用ip route和ip rule命令设置路由,以根据数据包的传出接口控制数据包的路由方式。对于我的示例,我将假定以下网络:
- eth0:
- 地址:192.168.0.2/24
- 默认网关:192.168.0.1
 
- eth1:
- 地址:192.168.1.2/24
- 默认网关:192.168.1.1
 
我将创建两个路由表,一个用于eth0的出站流量,称为alternate,另一个用于eth1的表,称为main。路由表main始终存在,并且是routeand ip route命令使用的普通表。大多数人从不处理任何其他表。要创建名为alternate的表,我们将以下行添加到/etc/iproute2/rt_tables:
10    alternate
主表的默认优先级为254。生效该路由表的规则由ip rule命令控制。默认情况下,该命令将打印出现有规则的列表,看起来应该像这样:
0:      from all lookup local 
32766:  from all lookup main 
32767:  from all lookup default 
这基本上表示它将在表中查找路由,该表local是内核为本地路由(例如我自己的IP地址)维护的特殊表。然后它将尝试表主表和表默认表。表的默认值通常为空白,因此如果main中没有匹配项,则没有主机路由。首先,让填充表与eth0的规则交替出现。
sudo ip route add table alternate 192.168.0.0/24 dev eth0
sudo ip route add table alternate 192.168.1.0/24 dev eth1
sudo ip route add table alternate default via 192.168.0.1
通常,您希望alternate表格看起来与main表格相似。唯一的区别是路由应该不同。如果您确实希望所有NFS,HTTP等流量都通过eth0上的默认网关通过,即使您的流量是发往eth1上的网络的,则您可能不想在上面添加第二行。下一步是添加何时使用此备用路由表的规则:
sudo ip rule add from 192.168.0.0/24 pref 10 table alternate
该规则表示,来自192.168.0网络上某个地址的所有流量都将使用alternate路由表而不是普通main表。最后一步是确保所有必须使用的客户端都eth0绑定到该客户端。使用wget,例如set --bind-address=192.168.0.2,对于NFS设置clientaddr=192.168.0.2挂载选项。如果将LibWWW与Perl一起使用,则可以在LWP :: UserAgent中设置localaddr选项以控制其绑定到的本地接口。如果碰巧有一个客户端,您将无法控制绑定,并且编译源也不是一种选择,那么您也许可以使用iptables规则来修改其地址,但这更像是一种技巧,可能无法正常工作。您将需要在nat表或mangle表的PREROUTING链中设置SNAT规则。您仍将需要上面给出的修改后的路由表才能起作用。
               
              
iftop,它们都显示正确的通信量。非常感谢。