I am trying to connect to a local application over UDP... I have tried blocking, non-blocking, connecting, not connection, reading and re-reading the Oracle docs, and am pretty much google-e-eyed now : Here's my latest refactoring:
package my.comm; import my.myMethods; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.DatagramChannel; import java.util.LinkedList; import java.util.Queue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** * * @author dave */ public class myConnection implements Runnable { DatagramChannel datagramChannel; private final String HOST = "127.0.0.1"; private final int PAYMENT_PORT = 4444; private final int MY_PORT = 8888; private final Queue<byte[]> incommingDataPackets = new LinkedList(); private final Queue<byte[]> outgoingDataPackets = new LinkedList(); private final ExecutorService exec = Executors.newFixedThreadPool(1); private final myMethods myMethods = new myMethods(); private static final Logger log = LogManager.getLogger(); public myConnection() throws IOException { datagramChannel = DatagramChannel.open(); datagramChannel.bind(new InetSocketAddress(HOST, PAYMENT_PORT)); datagramChannel.connect(new InetSocketAddress(HOST, MY_PORT)); datagramChannel.configureBlocking(true); myReceiver myReceiver = new myReceiver(this, datagramChannel.socket()); Thread mtdrThread = new Thread(myReceiver); exec.execute(mtdrThread); } public synchronized byte[] receiveData() { byte[] receivedBytes = new byte[0]; if(incommingDataPackets.size() > 0) { receivedBytes = incommingDataPackets.remove(); log.debug("receiving {}", myMethods.hexRepresentationOfByteBuffer(receivedBytes)); } return receivedBytes; } public synchronized void transmitData(byte[] sendData) { outgoingDataPackets.add(sendData); notifyAll(); } @Override public void run() { try { while(true){ while(outgoingDataPackets.size() > 0) { byte[] outgoingBytes = outgoingDataPackets.remove(); ByteBuffer outgoingByteBuffer = ByteBuffer.allocate(outgoingBytes.length); outgoingByteBuffer.clear(); outgoingByteBuffer.put(outgoingBytes); outgoingByteBuffer.flip(); log.debug("sending {}", myMethods.hexRepresentationOfByteBuffer(outgoingBytes)); int sentBytes = datagramChannel.write(outgoingByteBuffer); log.debug("sent {} bytes of data ", sentBytes); } } } catch (IOException ex) { log.fatal("IOException! {}", ex.getMessage()); } } public synchronized void addIncommingDatagramGuts(byte[] receivedBytes) { incommingDataPackets.add(receivedBytes); notifyAll(); } }
And the thread which receives the data:
package my.comm; import my.myMethods; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.nio.ByteBuffer; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger;/** * * @author Dave */ class myReceiver implements Runnable { private final DatagramSocket datagramSocket; private DatagramPacket datagramPacket; int MAX_PACKET_SIZE = 1500; byte[] incommingBytes = new byte[MAX_PACKET_SIZE]; private final myConnection myConnection; private final myMethods myMethods = new myMethods(); private static final Logger log = LogManager.getLogger(); myReceiver (myConnection myConnection, DatagramSocket datagramSocket) { this.myConnection = myConnection; this.datagramSocket = datagramSocket; } @Override public void run() { while(true) { try { datagramPacket = new DatagramPacket(incommingBytes, MAX_PACKET_SIZE); while(true){ datagramSocket.receive(datagramPacket); myConnection.addIncommingDatagramGuts(myMethods.trimFrame(datagramPacket.getData())); } } catch (IOException ex) { log.error("IOException! {}", ex.getMessage()); } } } }
All assistance is much appreciated!!!
*** EDIT ****
You need this file as well too compile the program - as well as jog4j2...
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package my; import java.io.Serializable; import java.nio.ByteBuffer; import java.text.DecimalFormat; import java.util.Arrays; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** * * @author Dave */ public class myMethods implements Serializable { private static final long serialVersionUID = 1L; private static final Logger log = LogManager.getLogger(); /* * used to remove frame escapes and apply the frame mask to the 'dirty' bytes */ public byte[] cleanData(byte[] buffer) { log.debug(hexRepresentationOfByteBuffer(buffer)); int cleanIndex = 0; byte[] cleaningBuffer = new byte[buffer.length]; byte[] cleanedBuffer; for(int index = 0; index < buffer.length; index++) { cleaningBuffer[cleanIndex++] = buffer[index] == myConstants.frameEscape ? (byte)(buffer[++index] ^ myConstants.frameMask) : buffer[index]; } cleanedBuffer = new byte[cleanIndex]; System.arraycopy(cleaningBuffer, 0, cleanedBuffer, 0, cleanIndex); log.debug(hexRepresentationOfByteBuffer(cleanedBuffer)); return cleanedBuffer; } public byte[] trimFrame(byte[] buffer) { if(buffer.length == 0) return new byte[0]; int trimmedIndex = 0; byte[] trimmedBytes; boolean foundFirstFrameFlag = false; boolean foundLastFrameFlag = false; for(int index = 0; index < buffer.length; index++){ if(!foundFirstFrameFlag && buffer[index] == Byte.parseByte("7E", 16)) { foundFirstFrameFlag = true; index++; } else foundLastFrameFlag = foundFirstFrameFlag && buffer[index] == Byte.parseByte("7E", 16) ? true : foundLastFrameFlag; if(foundLastFrameFlag) break; buffer[trimmedIndex++] = buffer[index]; } trimmedBytes = new byte[trimmedIndex]; System.arraycopy(buffer, 0, trimmedBytes, 0, trimmedIndex); return cleanData(trimmedBytes); } public String hexRepresentationOfByteBuffer(byte[] bytes) { StringBuilder stringBuilder = new StringBuilder(); for (int index = 0; index < bytes.length; index++) { stringBuilder.append(hexRepresentationOfByte(bytes[index])); if(index<bytes.length - 1) stringBuilder.append(", "); } return stringBuilder.toString(); } public String hexRepresentationOfByte(byte theByte) { return String.format("%02x", theByte).toUpperCase(); } }