Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JAVA设置/从多个(UDP)中选择特定NIC_Java_Udp_Set_Datagram_Nic - Fatal编程技术网

JAVA设置/从多个(UDP)中选择特定NIC

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

我正在尝试用JAVA发送带有数据报的UDP,我的机器有几个具有不同IP的NIC

如何设置要从哪个NIC发送数据包??(假设我的机器上有多台??)

编辑一

我没有使用Socket,我使用的是DatagramSocket,并尝试这样进行绑定:

/*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");