@@ -0,0 +1,3312 @@
+package com.paritytrading.nassau.util;%0A%0Aimport com.paritytrading.nassau.MessageListener;%0Aimport com.paritytrading.nassau.moldudp64.MoldUDP64Client;%0Aimport com.paritytrading.nassau.moldudp64.MoldUDP64ClientState;%0Aimport com.paritytrading.nassau.moldudp64.MoldUDP64ClientStatusListener;%0Aimport java.io.IOException;%0Aimport java.net.InetSocketAddress;%0Aimport java.net.NetworkInterface;%0Aimport java.net.StandardProtocolFamily;%0Aimport java.net.StandardSocketOptions;%0Aimport java.nio.channels.DatagramChannel;%0Aimport java.nio.channels.SelectionKey;%0Aimport java.nio.channels.Selector;%0Aimport java.util.Set;%0A%0A/**%0A * Utility methods for working with the NASDAQ MoldUDP64 1.00 protocol.%0A */%0Apublic class MoldUDP64 %7B%0A%0A    private MoldUDP64() %7B%0A    %7D%0A%0A    /**%0A     * Receive messages. Invoke the message listener on each message. Continue%0A     * until a packet indicating the End of Session is received.%0A     *%0A     * @param multicastInterface the multicast interface%0A     * @param multicastGroup the multicast group%0A     * @param requestAddress the request address%0A     * @param listener a message listener%0A     * @throws IOException if an I/O error occurs%0A     */%0A    public static void receive(NetworkInterface multicastInterface,%0A            InetSocketAddress multicastGroup, InetSocketAddress requestAddress,%0A            MessageListener listener) throws IOException %7B%0A        DatagramChannel channel = DatagramChannel.open(StandardProtocolFamily.INET);%0A%0A        channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);%0A        channel.bind(new InetSocketAddress(multicastGroup.getPort()));%0A        channel.join(multicastGroup.getAddress(), multicastInterface);%0A        channel.configureBlocking(false);%0A%0A        DatagramChannel requestChannel = DatagramChannel.open(StandardProtocolFamily.INET);%0A%0A        requestChannel.configureBlocking(false);%0A%0A        StatusListener statusListener = new StatusListener();%0A%0A        try (Selector selector = Selector.open();%0A                MoldUDP64Client client = new MoldUDP64Client(channel, requestChannel,%0A                    requestAddress, listener, statusListener)) %7B%0A            SelectionKey channelKey = channel.register(selector, SelectionKey.OP_READ);%0A%0A            SelectionKey requestChannelKey = requestChannel.register(selector, SelectionKey.OP_READ);%0A%0A            while (statusListener.receive) %7B%0A                while (selector.select() == 0);%0A%0A                Set%3CSelectionKey%3E selectedKeys = selector.selectedKeys();%0A%0A                if (selectedKeys.contains(channelKey))%0A                    client.receive();%0A%0A                if (selectedKeys.contains(requestChannelKey))%0A                    client.receiveResponse();%0A%0A                selectedKeys.clear();%0A            %7D%0A        %7D%0A    %7D%0A%0A    private static class StatusListener implements MoldUDP64ClientStatusListener %7B%0A%0A        boolean receive = true;%0A%0A        @Override%0A        public void state(MoldUDP64Client session, MoldUDP64ClientState next) %7B%0A        %7D%0A%0A        @Override%0A        public void downstream(MoldUDP64Client session) %7B%0A        %7D%0A%0A        @Override%0A        public void request(MoldUDP64Client session, long sequenceNumber, int requestedMessageCount) %7B%0A        %7D%0A%0A        @Override%0A        public void endOfSession(MoldUDP64Client session) %7B%0A            receive = false;%0A        %7D%0A%0A    %7D%0A%0A%7D%0A

Add MoldUDP64 to utilities