Skip to content
Snippets Groups Projects
Commit 941d3167 authored by Terry D. Norbraten's avatar Terry D. Norbraten
Browse files

implement leaving mc group for socket upon thread kill. object creation

outside of loops
parent c287afa0
No related branches found
No related tags found
No related merge requests found
......@@ -9,6 +9,8 @@ import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* DisNetworking.java created on Jul 29, 2019
......@@ -31,6 +33,13 @@ public class DisNetworking
private int DIS_PORT = 3000;
private String MCAST_GROUP = "230.0.0.0";
private static final int MAX_DIS_PDU_SIZE = 8192;
private ByteArrayOutputStream baos;
private DataOutputStream dos;
private InetAddress maddr;
private InetSocketAddress group;
private NetworkInterface ni;
public DisNetworking()
{
......@@ -41,6 +50,15 @@ public class DisNetworking
{
DIS_PORT = port;
MCAST_GROUP = mcastgroup;
try {
maddr = InetAddress.getByName(MCAST_GROUP);
} catch (UnknownHostException ex) {
Logger.getLogger(DisNetworking.class.getName()).log(Level.SEVERE, null, ex);
}
group = new InetSocketAddress(maddr, DIS_PORT);
ni = DisThreadedNetIF.findIp4Interface();
baos = new ByteArrayOutputStream();
dos = new DataOutputStream(baos);
}
public int getPort()
......@@ -74,16 +92,12 @@ public class DisNetworking
}
private MulticastSocket rsocket;
InetSocketAddress group;
InetAddress maddr;
byte buffer[];
DatagramPacket packet;
public BuffAndLength receiveRawPdu() throws IOException
{
rsocket = new MulticastSocket(DIS_PORT);
maddr = InetAddress.getByName(MCAST_GROUP);
group = new InetSocketAddress(maddr, DIS_PORT);
rsocket.joinGroup(group, DisThreadedNetIF.findIp4Interface());
rsocket.joinGroup(group, ni);
buffer = new byte[MAX_DIS_PDU_SIZE];
packet = new DatagramPacket(buffer, buffer.length);
......@@ -91,34 +105,31 @@ public class DisNetworking
rsocket.receive(packet); //blocks here waiting for next DIS pdu to be received on broadcast IP and specified port
//System.out.println("packet received from " + packet.getSocketAddress());
rsocket.leaveGroup(group, DisThreadedNetIF.findIp4Interface());
rsocket.leaveGroup(group, ni);
rsocket.close();
rsocket = null;
return new BuffAndLength(packet.getData(), packet.getLength());
}
ByteArrayOutputStream baos;
DataOutputStream dos;
public void sendPdu(Pdu pdu) throws Exception
{
// turn object into byte stream
baos = new ByteArrayOutputStream();
dos = new DataOutputStream(baos);
pdu.marshal(dos);
sendRawPdu(baos.toByteArray());
baos.reset();
}
MulticastSocket ssocket;
private MulticastSocket ssocket;
public void sendRawPdu(byte[] data) throws IOException
{
ssocket = new MulticastSocket();
maddr = InetAddress.getByName(MCAST_GROUP);
ssocket.joinGroup(group, ni);
// load byte buffer into packet and send
packet = new DatagramPacket(data, data.length, maddr, DIS_PORT);
ssocket.send(packet);
ssocket.leaveGroup(group, ni);
ssocket.close();
ssocket = null;
//System.out.println("sent to " + maddr.getHostAddress() + ":" + DIS_PORT);
......
......@@ -6,21 +6,20 @@ package edu.nps.moves.dis7.utilities;
import edu.nps.moves.dis7.Pdu;
import edu.nps.moves.dis7.enumerations.DISPDUType;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.*;
import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* DisThreadedNetIF.java created on Jul 29, 2019
* This is a thread-safe, multicast DIS network interface class.
* It is a singleton, meaning one instance per VM. If a DIS needs to send and receive over
* more than one network address, this class can be modified to be multiply instantiated;
* MOVES Institute Naval Postgraduate School, Monterey, CA, USA www.nps.edu
*
*
* @author Mike Bailey, jmbailey@nps.edu
* @version $Id$
*/
......@@ -59,6 +58,12 @@ public class DisThreadedNetIF
private int disPort;
private String mcastGroup;
private boolean killed = false;
private InetAddress maddr;
private InetSocketAddress group;
private NetworkInterface ni;
private MulticastSocket ssocket = null;
private MulticastSocket rsocket = null;
public DisThreadedNetIF()
{
......@@ -69,6 +74,13 @@ public class DisThreadedNetIF
{
disPort = port;
mcastGroup = mcastgroup;
try {
maddr = InetAddress.getByName(mcastGroup);
} catch (UnknownHostException ex) {
Logger.getLogger(DisThreadedNetIF.class.getName()).log(Level.SEVERE, null, ex);
}
group = new InetSocketAddress(maddr, disPort);
ni = findIp4Interface();
init();
}
......@@ -164,9 +176,6 @@ public class DisThreadedNetIF
private Thread sender;
private Thread receiver;
private MulticastSocket socket = null;
private InetAddress maddr;
private void init()
{
receiver = new Thread(receiveThread, "DisThreadedNetIF receive thread");
......@@ -185,20 +194,16 @@ public class DisThreadedNetIF
byte buffer[] = new byte[MAX_DIS_PDU_SIZE];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
InetSocketAddress group;
Pdu pdu;
ByteBuffer byteBuffer;
while (!killed) { // keep trying on error
try {
socket = new MulticastSocket(disPort);
maddr = InetAddress.getByName(mcastGroup);
group = new InetSocketAddress(maddr, disPort);
socket.joinGroup(group, findIp4Interface());
rsocket = new MulticastSocket(disPort);
rsocket.joinGroup(group, ni);
while (!killed) {
socket.receive(packet); //blocks here waiting for next DIS pdu to be received on multicast IP and specified port
rsocket.receive(packet); //blocks here waiting for next DIS pdu to be received on multicast IP and specified port
toRawListeners(packet.getData(), packet.getLength());
// the PduFactory will wrap data in a ByteBuffer
......@@ -213,16 +218,15 @@ public class DisThreadedNetIF
}
}
catch (IOException ex) {
if (socket != null) {
socket.close();
socket = null;
if (rsocket != null) {
rsocket.close();
rsocket = null;
}
System.err.println("Exception in DISThreadedNetIF receive thread: " + ex.getLocalizedMessage());
System.err.println("Retrying in 5 seconds");
System.err.println("Retrying in 1 second");
}
if (!killed)
sleep(5000);
sleep(250);
}
};
......@@ -234,37 +238,38 @@ public class DisThreadedNetIF
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
while (!killed) { // keep trying on error
try {
ssocket = new MulticastSocket(disPort);
ssocket.joinGroup(group, ni);
while (!killed) {
pdu = pdus2send.take();
// turn object into byte stream
pdu.marshal(dos);
data = baos.toByteArray();
// Since we don't know the size of the PDU, reluctantly, we create
// new packet object each listen cycle
// Since we don't know the size of the PDU, reluctantly, we create a
// new packet here when we finally know
packet = new DatagramPacket(data, data.length, maddr, disPort);
socket.send(packet);
ssocket.send(packet);
baos.reset();
}
}
catch (InterruptedException ex) {
// probably killed
}
catch (Exception ex) {
if (socket != null) {
socket.close();
socket = null;
if (ssocket != null) {
ssocket.close();
ssocket = null;
}
System.err.println("Exception in DISThreadedNetIF send thread: " + ex.getLocalizedMessage());
System.err.println("Retrying in 5 seconds");
System.err.println("Retrying in 1 second");
}
if (!killed)
sleep(5000);
sleep(250);
}
};
private void toListeners(Pdu pdu)
......@@ -291,6 +296,20 @@ public class DisThreadedNetIF
killed = true;
sender.interrupt();
receiver.interrupt();
try {
if (ssocket != null && !ssocket.isClosed()) {
ssocket.leaveGroup(group, ni);
ssocket.close();
ssocket = null;
}
if (rsocket != null && !rsocket.isClosed()) {
rsocket.leaveGroup(group, ni);
rsocket.close();
rsocket = null;
}
} catch (IOException ex) {
Logger.getLogger(DisThreadedNetIF.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void sleep(long ms)
......@@ -298,22 +317,25 @@ public class DisThreadedNetIF
try {
Thread.sleep(ms);
}
catch (InterruptedException ex) {
}
catch (InterruptedException ex) {}
}
/** Find proper interface
* @return a network interface to use to join multicast group
* @throws java.net.SocketException if something goes wrong
* @return a network interface to use to join a multicast group
*/
public static NetworkInterface findIp4Interface() throws SocketException
public static NetworkInterface findIp4Interface()
{
Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
Enumeration<NetworkInterface> ifaces = null;
try {
ifaces = NetworkInterface.getNetworkInterfaces();
} catch (SocketException ex) {
Logger.getLogger(DisThreadedNetIF.class.getName()).log(Level.SEVERE, null, ex);
}
NetworkInterface nif;
Enumeration<InetAddress> addresses;
InetAddress addr;
while (ifaces.hasMoreElements()) {
while (ifaces != null && ifaces.hasMoreElements()) {
nif = ifaces.nextElement();
addresses = nif.getInetAddresses();
while (addresses.hasMoreElements()) {
......
package edu.nps.moves.dis7.utilities;
import edu.nps.moves.dis7.Pdu;
import edu.nps.moves.dis7.utilities.PduFactory;
import edu.nps.moves.dis7.utilities.stream.PduRecorder;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
......@@ -63,25 +63,28 @@ public class LogCompare
int lineno = 0;
boolean goodmatch = true;
try {
BufferedReader reader1 = new BufferedReader(new FileReader(file1));
BufferedReader reader2 = new BufferedReader(new FileReader(file2));
try (BufferedReader reader1 = new BufferedReader(new FileReader(file1)); BufferedReader reader2 = new BufferedReader(new FileReader(file2))) {
String line1 = reader1.readLine();
String line2 = reader2.readLine();
lineno++;
String[] sa1;
String[] sa2;
byte[] ba1;
byte[] ba2;
Pdu pdu1;
Pdu pdu2;
while (line1 != null && line2 != null) {
mainblock:
{
if (line1.equals(line2))
break mainblock;
break mainblock;
if (line1.startsWith(PduRecorder.COMMENT_MARKER) || line2.startsWith(PduRecorder.COMMENT_MARKER))
break mainblock;
break mainblock;
String[] sa1 = line1.split(",");
String[] sa2 = line2.split(",");
sa1 = line1.split(",");
sa2 = line2.split(",");
if (sa1.length != sa2.length) {
System.err.println("Error: parsing error. ASCII 2-part, comma-separated expected. Lines follow.");
System.err.println(line1);
......@@ -93,8 +96,8 @@ public class LogCompare
if (sa1[1].equals(sa2[1]))
break mainblock;
byte[] ba1 = decdr.decode(sa1[1]);
byte[] ba2 = decdr.decode(sa2[1]);
ba1 = decdr.decode(sa1[1]);
ba2 = decdr.decode(sa2[1]);
if (ba1.length != ba2.length) {
System.out.println("line " + lineno + ": lengths differ. Lines follow.");
......@@ -103,8 +106,8 @@ public class LogCompare
break mainblock;
}
Pdu pdu1 = factory.createPdu(ba1);
Pdu pdu2 = factory.createPdu(ba2);
pdu1 = factory.createPdu(ba1);
pdu2 = factory.createPdu(ba2);
if (pdu1.equals(pdu2)) // use generated equals method
break mainblock;
......@@ -121,6 +124,7 @@ public class LogCompare
line1 = reader1.readLine();
line2 = reader2.readLine();
lineno++;
}
System.out.println("End of compare. There were " + (goodmatch ? "no " : "one or more ") + "errors");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment