JAVA设置/从多个(UDP)中选择特定NIC
我正在尝试用JAVA发送带有数据报的UDP,我的机器有几个具有不同IP的NIC 如何设置要从哪个NIC发送数据包??(假设我的机器上有多台??) 编辑一 我没有使用Socket,我使用的是DatagramSocket,并尝试这样进行绑定:JAVA设置/从多个(UDP)中选择特定NIC,java,udp,set,datagram,nic,Java,Udp,Set,Datagram,Nic,我正在尝试用JAVA发送带有数据报的UDP,我的机器有几个具有不同IP的NIC 如何设置要从哪个NIC发送数据包??(假设我的机器上有多台??) 编辑一 我没有使用Socket,我使用的是DatagramSocket,并尝试这样进行绑定: /*binding */ DatagramSocket ds = new DatagramSocket(1111); NetworkInterface nif = NetworkInterface.getByIndex(nicI
/*binding */
DatagramSocket ds = new DatagramSocket(1111);
NetworkInterface nif = NetworkInterface.getByIndex(nicIndex);
Enumeration<InetAddress> nifAddresses = nif.getInetAddresses();
ds.bind(new InetSocketAddress(nifAddresses.nextElement(), 0));
/*绑定*/
DatagramSocket ds=新的DatagramSocket(1111);
NetworkInterface nif=NetworkInterface.getByIndex(nicIndex);
枚举nifAddresses=nif.getInetAddresses();
bind(新的InetSocketAddress(nifAddresses.nextElement(),0));
但是当我这样做的时候,我再也无法连接了(或者无法获取数据包…)。
问题是我有两个NIC,但一个用于内部网络,另一个用于Internet。。
我需要我所有的服务器数据只放在内部数据上
编辑二
请澄清。
此应用程序是一个服务器-服务器有2个NIC。一个用于LAN,一个用于WAN
对我来说,另一种方法是以某种方式指定路由,这意味着告诉每个数据包确切地使用哪个NIC
如何在JAVA中执行这样的路由???Socket类有一个接受
localAddr
参数的类。这可能适用于您
编辑:
1) 不要在Java中执行路由,将其留给操作系统
2) 我相信你来过
3) 服务器可以绑定到0.0.0
(即机器上的任何IP),如果您仅在DatagramSocket
构造函数中指定端口,则会发生这种情况;如果您选择DatagramSocket(int-port,InetAddress laddr)
构造函数,则服务器可以绑定到特定接口-这是您应该做的
4) 然后,客户端发送它需要发送的任何内容,服务器可以使用在3)中创建的套接字和packet.getAddress()/packet.getPort()目的地进行响应
干杯,来自教程文档,
要发送数据,系统将确定使用哪个接口。但是,如果您有首选项或需要指定要使用哪个NIC,您可以在系统中查询适当的接口,并在要使用的接口上找到地址
网络接口可以通过编程方式访问,枚举en=NetworkInterface.getNetworkInterfaces() 迭代每一次,您可以获得与之关联的InetAddress,并使用InetAddress构造数据报套接字。
在这个问题上有很好的信息-
希望对您有所帮助,这里是我使用的大部分完整代码。在我的情况下,我知道连接使用的IP地址前缀。您可能需要查找接口的名称,并将其与存储在配置文件中的值进行比较 请注意,使用MulticastSocket而不是DatagramSocket,因此setNetworkInterface方法可用于绑定所需的接口。由于MulticastSocket是DatagramSocket的子类,因此开关通常不会导致任何问题
@Override
public void connect() throws InterruptedException
{
NetworkInterface iFace;
iFace = findNetworkInterface();
connectControlBoard(iFace);
connectUTBoards(iFace);
}//end of Capulin1::connect
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Capulin1:findNetworkInterface
//
// Finds the network interface for communication with the remotes. Returns
// null if no suitable interface found.
//
// The first interface which is connected and has an IP address beginning with
// 169.254.*.* is returned.
//
// NOTE: If more than one interface is connected and has a 169.254.*.*
// IP address, the first one in the list will be returned. Will need to add
// code to further differentiate the interfaces if such a set up is to be
// used. Internet connections will typically not have such an IP address, so
// a second interface connected to the Internet will not cause a problem with
// the existing code.
//
// If a network interface is not specified for the connection, Java will
// choose the first one it finds. The TCP/IP protocol seems to work even if
// the wrong interface is chosen. However, the UDP broadcasts for wake up calls
// will not work unless the socket is bound to the appropriate interface.
//
// If multiple interface adapters are present, enabled, and running (such as
// an Internet connection), it can cause the UDP broadcasts to fail.
//
public NetworkInterface findNetworkInterface()
{
logger.logMessage("");
NetworkInterface iFace = null;
try{
logger.logMessage("Full list of Network Interfaces:" + "\n");
for (Enumeration<NetworkInterface> en =
NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
logger.logMessage(" " + intf.getName() + " " +
intf.getDisplayName() + "\n");
for (Enumeration<InetAddress> enumIpAddr =
intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
String ipAddr = enumIpAddr.nextElement().toString();
logger.logMessage(" " + ipAddr + "\n");
if(ipAddr.startsWith("/169.254")){
iFace = intf;
logger.logMessage("==>> Binding to this adapter...\n");
}
}
}
}
catch (SocketException e) {
logger.logMessage(" (error retrieving network interface list)" + "\n");
}
return(iFace);
}//end of Capulin1::findNetworkInterface
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Capulin1::connectControlBoards
//
public void connectControlBoard(NetworkInterface pNetworkInterface)
throws InterruptedException
{
logger.logMessage("Broadcasting greeting to all Control boards...\n");
MulticastSocket socket;
try{
socket = new MulticastSocket(4445);
if (pNetworkInterface != null) {
try{
socket.setNetworkInterface(pNetworkInterface);
}catch (IOException e) {}//let system bind to default interface
}
}
catch (IOException e) {
logSevere(e.getMessage() + " - Error: 204");
logger.logMessage("Couldn't create Control broadcast socket.\n");
return;
}
...use the socket here...
@覆盖
public void connect()引发InterruptedException
{
网络接口;
iFace=findNetworkInterface();
连接控制板(iFace);
连接板(iFace);
}//Capulin1的末尾::connect
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//Capulin1:findNetworkInterface
//
//查找与远程设备通信的网络接口。返回
//如果未找到合适的接口,则为null。
//
//连接的第一个接口,其IP地址以
//返回169.254.*.*。
//
//注意:如果连接了多个接口,并且接口号为169.254.**
//IP地址,将返回列表中的第一个。将需要添加
//如果要进行这样的设置,则代码可进一步区分接口
//Internet连接通常没有这样的IP地址,因此
//连接到Internet的第二个接口不会导致网络故障
//现行守则。
//
//如果没有为连接指定网络接口,Java将
//选择它找到的第一个。TCP/IP协议似乎可以工作,即使
//选择了错误的接口。但是,UDP广播用于唤醒调用
//除非套接字绑定到适当的接口,否则将无法工作。
//
//如果存在、启用并运行多个接口适配器(例如
//互联网连接),它可能导致UDP广播失败。
//
公共网络接口findNetworkInterface()
{
logger.logMessage(“”);
网络接口iFace=null;
试一试{
logger.logMessage(“网络接口的完整列表:“+”\n”);
用于(枚举)=
NetworkInterface.getNetworkInterfaces();en.hasMoreElements();){
NetworkInterface intf=en.nextElement();
logger.logMessage(“+intf.getName()+”)+
intf.getDisplayName()+“\n”);
对于(枚举enumIpAddr)=
intf.getInetAddresses();enumIpAddr.hasMoreElements();){
字符串ipAddr=EnumIPADR.nextElement().toString();
logger.logMessage(“+ipAddr+”\n”);
if(ipAddr.startsWith(“/169.254”)){
iFace=intf;
logger.logMessage(“==>>绑定到此适配器…\n”);
}
}
}
}
捕获(SocketException e){
logger.logMessage(“(检索网络接口列表时出错)”+“\n”);
}
返回(iFace);
}//Capulin1::findNetworkInterface结束
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//Capulin1::连接控制板
//
公共无效连接控制板(网络接口pNetworkInterface)
抛出中断EXCE
//set Network Interface
NetworkInterface nif = NetworkInterface.getByName("tun0");
if(nif==null){
System.err.println("Error getting the Network Interface");
return;
}
System.out.println("Preparing to using the interface: "+nif.getName());
Enumeration<InetAddress> nifAddresses = nif.getInetAddresses();
InetSocketAddress inetAddr= new InetSocketAddress(nifAddresses.nextElement(),0);
//socket.bind(new InetSocketAddress(nifAddresses.nextElement(), 0));
DatagramSocket socket = new DatagramSocket(inetAddr);
System.out.println("Interface setted");