Closed terrypacker closed 5 years ago
Java only has setReuseAddress AFAICS. What is the proposal here? To change the name of the field/method?
Looks like you are right... for now. SO_REUSEPORT should be present in Java 9.
Now that Java 9 is out, I'd like to bring back the attention on this issue. :-)
(Hopefully this simple change would allow multiple instances of BACnet4J to run on a single IP/port)
This appears to have been added, so this issue can probably be closed.
A side question : is it possible to have multiple Bacnet devices using the same IP and communicate normally between them? I've given it a quick try, but all the devices on the same IP are answering the readProperty requests at the same time, even if they are the one that sent the request..
@Frozenlock I'm going to close this but I wrote a test awhile back so here is a starting point if you want:
/**
* Copyright (C) 2018 Infinite Automation Software. All rights reserved.
*/
package com.infiniteautomation.bacnet4j.npdu.ip;
import java.net.InterfaceAddress;
import java.util.List;
import org.junit.Assume;
import org.junit.Test;
import com.serotonin.bacnet4j.LocalDevice;
import com.serotonin.bacnet4j.npdu.ip.IpNetwork;
import com.serotonin.bacnet4j.npdu.ip.IpNetworkBuilder;
import com.serotonin.bacnet4j.transport.DefaultTransport;
import com.serotonin.bacnet4j.transport.Transport;
/**
* @author Terry Packer
*
*/
public class MulltipleLocalDevices {
@Test
public void testMultipleLocalDevices() throws Exception {
List<InterfaceAddress> usable = BacnetIpUtils.listUsableBACnetInterfaces();
Assume.assumeTrue(usable.size() > 0);
InterfaceAddress address = usable.get(0);
String bindAddress = address.getAddress().toString().split("/")[1];
String broadcastAddress = address.getBroadcast().toString().split("/")[1];
//Configure the first network, ensure we set reuse address
IpNetwork networkOne = new IpNetworkBuilder()
.withLocalBindAddress(bindAddress)
.withBroadcast(broadcastAddress, address.getNetworkPrefixLength())
.withLocalNetworkNumber(1).withPort(9000).withReuseAddress(true).build();
Transport transportOne = new DefaultTransport(networkOne);
LocalDevice localDeviceOne = new LocalDevice(1, transportOne);
IpNetwork networkTwo = new IpNetworkBuilder()
.withLocalBindAddress(bindAddress)
.withBroadcast(broadcastAddress, address.getNetworkPrefixLength())
.withLocalNetworkNumber(1).withPort(9000).withReuseAddress(true).build();
Transport transportTwo = new DefaultTransport(networkTwo);
LocalDevice localDeviceTwo = new LocalDevice(2, transportTwo);
localDeviceOne.initialize();
localDeviceTwo.initialize();
}
}
From a comment on this commit cfd52615fa3bfb93ce8150ecbaa8ec81323960c9
How about reusePort to (hopefully) allow multiple instances to use the same interface?
SO_REUSEPORT is what most people would expect SO_REUSEADDR to be. Basically, SO_REUSEPORT allows you to bind an arbitrary number of sockets to exactly the same source address and port as long as all prior bound sockets also had SO_REUSEPORT set before they were bound.
More info here