Non-blocking UDP datagram replicator
A class that listens to a UDP port and collects all the datagrams and then rebroadcasts those datagrams to other ports. This is useful for several reasons. I use it when stress testing UDP clients because I can subscribe to 1000 client sockets while only really having a single legitimate datasource.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | public class Replicator { private final AsyncDatagramServer aserver; public Replicator(final int port, final Collection<DataSinkPoint> endPoints) throws Exception { aserver = new AsyncDatagramServer(port, new AsyncDatagramServer.AsyncDatagramServerListener() { @Override public void recieveDatagram(ByteBuffer buffer) { try { for(final DataSinkPoint d: endPoints) { d.send(buffer.duplicate()); } } catch (final Exception e) { e.printStackTrace(); } } }); } private static class AsyncDatagramServer { private boolean running = true; public AsyncDatagramServer(final int port, final AsyncDatagramServerListener listener) throws Exception { new Thread(){ @Override public void run() { try { startSocket(port, listener); } catch (final Exception e) { throw new RuntimeException(e); } } }.start(); } public interface AsyncDatagramServerListener { void recieveDatagram(ByteBuffer buffer); } public void shutdown() { running = false; } private void startSocket(final int port, AsyncDatagramServerListener listener) throws IOException, SocketException, ClosedChannelException, Exception { DatagramChannel serverChannel = DatagramChannel.open(); Selector selector = Selector.open(); DatagramSocket sock = serverChannel.socket(); sock.setReuseAddress(true); sock.bind (new InetSocketAddress (port)); serverChannel.configureBlocking (false); serverChannel.register(selector, SelectionKey.OP_READ); ByteBuffer buffer = ByteBuffer.allocate(2048); while (running) { if(selector.select(500) > 0) { processData(listener, selector, buffer); } } selector.close(); serverChannel.close(); } private void processData(AsyncDatagramServerListener listener, Selector selector, ByteBuffer buffer) throws Exception { Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while (it.hasNext()) { final SelectionKey key = it.next(); if (key.isReadable()) { DatagramChannel channel = (DatagramChannel) key.channel(); buffer.clear(); if (channel.receive(buffer) != null) { buffer.flip(); listener.recieveDatagram(buffer.duplicate()); } } it.remove(); } } } public void shutdown() { aserver.shutdown(); } public interface DataSinkPoint { void send(ByteBuffer buffer) throws IOException; } private static class DataSinkPointImpl implements DataSinkPoint { private final DatagramSocket socket; public DataSinkPointImpl(SocketAddress address) throws Exception { socket = new DatagramSocket(); socket.connect(address); } @Override public void send(ByteBuffer buffer) throws IOException { socket.send(new DatagramPacket(buffer.array(), 0, buffer.limit())); } } } |
Usage:
1 2 3 4 5 6 7 8 9 10 11 12 | public static void main(String[] args) throws Exception { Collection<DataSinkPoint> endPoints = new ArrayList<DataSinkPoint>(); for(int i = 4000; i < 5000; i++) { endPoints.add(new DataSinkPointImpl( new InetSocketAddress("127.0.0.1", i))); } final Replicator r = new Replicator(3000, endPoints); Thread.sleep(5000); r.shutdown(); System.out.println("done."); } |
Announcing – “Announce” for Android
Announce is an application for Android 2.0 and above. It intercepts incoming calls and and reads the name of the caller aloud. You can also record custom voice tags to use instead of the text to speech engine.
Project Page: http://www.peterfranza.com/projects/announce-for-android/
Price: Free (That’s a good value)
Enjoy.
BitArrayInputStream
Sometime you just have to read the bits one by one at least now you don’t need to write your own class to do it. This class works for ‘Little Endian’ or ‘Big Endian’.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | import java.io.IOException; import java.io.InputStream; public class BitArrayInputStream { private final BitDirection direction; private final InputStream inputStream; private int currentByte; private int currentPosition = -1; public BitArrayInputStream(InputStream inputStream) { this(BitDirection.HIGHLOW, inputStream); } public BitArrayInputStream(BitDirection direction, InputStream inputStream) { this.inputStream = inputStream; this.direction = direction; } public int readBit() throws IOException { if(currentPosition == -1) { currentByte = inputStream.read(); if(currentByte == -1) { return -1; } currentPosition = 0; } int c = -1; if(direction.equals(BitDirection.HIGHLOW)) { c = (currentByte << currentPosition & 0x80) >> 7; } else { c = currentByte >> currentPosition & 0x1; } currentPosition += 1; if(currentPosition >= 8) { currentPosition = -1; } return c; } public static enum BitDirection {HIGHLOW, LOWHIGH} } |
And here is a unit test for it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | public class BitArrayInputStreamTest extends TestCase { public void testInit() throws Exception { assertNotNull(new BitArrayInputStream(null)); } public void testReadBits() throws Exception { BitArrayInputStream i = new BitArrayInputStream( new ByteArrayInputStream(new byte[] {(byte) 0xA3})); assertEquals(1, i.readBit()); assertEquals(0, i.readBit()); assertEquals(1, i.readBit()); assertEquals(0, i.readBit()); assertEquals(0, i.readBit()); assertEquals(0, i.readBit()); assertEquals(1, i.readBit()); assertEquals(1, i.readBit()); } public void testReadBitsLowHigh() throws Exception { BitArrayInputStream i = new BitArrayInputStream(BitDirection.LOWHIGH, new ByteArrayInputStream(new byte[] {(byte) 0xA3})); assertEquals(1, i.readBit()); assertEquals(1, i.readBit()); assertEquals(0, i.readBit()); assertEquals(0, i.readBit()); assertEquals(0, i.readBit()); assertEquals(1, i.readBit()); assertEquals(0, i.readBit()); assertEquals(1, i.readBit()); } public void testReadBitsEnd() throws Exception { BitArrayInputStream i = new BitArrayInputStream( new ByteArrayInputStream(new byte[] {(byte) 0xA3})); assertEquals(1, i.readBit()); assertEquals(0, i.readBit()); assertEquals(1, i.readBit()); assertEquals(0, i.readBit()); assertEquals(0, i.readBit()); assertEquals(0, i.readBit()); assertEquals(1, i.readBit()); assertEquals(1, i.readBit()); assertEquals(-1, i.readBit()); } public void testReadBitsMultiByte() throws Exception { BitArrayInputStream i = new BitArrayInputStream( new ByteArrayInputStream( new byte[] {(byte) 0xA3, (byte) 0xB6})); assertEquals(1, i.readBit()); assertEquals(0, i.readBit()); assertEquals(1, i.readBit()); assertEquals(0, i.readBit()); assertEquals(0, i.readBit()); assertEquals(0, i.readBit()); assertEquals(1, i.readBit()); assertEquals(1, i.readBit()); assertEquals(1, i.readBit()); assertEquals(0, i.readBit()); assertEquals(1, i.readBit()); assertEquals(1, i.readBit()); assertEquals(0, i.readBit()); assertEquals(1, i.readBit()); assertEquals(1, i.readBit()); assertEquals(0, i.readBit()); } } |
Look Mom, No Typing
Always wanted to leave a comment about something you’ve read on my site, but couldn’t be bothered to type a response. Well now you can using my new Google Voice Call widget. Now you don’t have to worry about carpel tunnel or any of that fancy spelling stuff. Really all you need is a mouth and a phone.
Ignore Compiler Warnings
Let me be upfront, I will be the first person to tell you that you should treat a warning as if it were an error. The compiler is trying to tell you something, it wants to help you. The very smart people who are designing our compiler aren’t identifying code patterns and exposing them as warnings for their health, so come on people … FIX YOUR WARNINGS!
Ok, now that I got that out of the way, we come to the special case. Third party source code generation tools, I actually love generated source, don’t ask me why but I find it much easier to deal with than all the mucking around you could do in meta-code etc. Just give me a plain ‘ol class that I can use. The drawback to generated source is some of the generators are pretty rough when it comes to warnings. They might have unneeded imports, referenced untyped classes, who knows. We all can agree that it would be optimal if the generators would just produce warning free code, and if it is in your power join up with some of these open-source projects and actually fix them (you’d be my hero).
When that isn’t an option I’d just ignore them, I’m adding an ant task that can read in a fileset and append warning suppression annotations to the class headings. Just remember you have not fixed anything, but to be perfectly practical you may never fix these things.
Download Jar File: suppresswarnings-05.jar
Usage:


