/** * Copyright (C) 2009-2013 Barchart, Inc. <http://www.barchart.com/> * * All rights reserved. Licensed under the OSI BSD License. * * http://www.opensource.org/licenses/bsd-license.php */ package com.barchart.udt.net; import static org.junit.Assert.*; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import org.junit.Test; import util.TestAny; import util.UnitHelp; /** * Sets up a simple UDT client and server to test sending messages between them. */ public class TestSimple extends TestAny { @Test public void testUdtClientServer() throws Exception { // This will hold the message received on the server to make sure // we're getting the right one across multiple threads. final AtomicReference<String> ref = new AtomicReference<String>(); final InetSocketAddress serverAddress = UnitHelp.localSocketAddress(); startThreadedServer(serverAddress, ref); final Socket clientSocket = new NetSocketUDT(); final InetSocketAddress clientAddress = UnitHelp.localSocketAddress(); clientSocket.bind(clientAddress); assertTrue("Socket not bound!!", clientSocket.isBound()); clientSocket.connect(serverAddress); assertTrue("Socket not connected!", clientSocket.isConnected()); final String msgOut = "HELLO UDT"; final OutputStream os = clientSocket.getOutputStream(); os.write(msgOut.getBytes()); synchronized (ref) { final String str = ref.get(); if (str == null || !str.equals(msgOut)) { ref.wait(3 * 1000); } } assertEquals(msgOut.length(), ref.get().length()); assertEquals("Did not get the expected message on the server!!", msgOut, ref.get()); log.info("Server received: |{}|", ref.get()); final byte[] received = new byte[1234]; final InputStream is = clientSocket.getInputStream(); final int readCount = is.read(received); assertEquals(msgOut, new String(received, 0, readCount)); } private void startThreadedServer(final InetSocketAddress serverAddress, final AtomicReference<String> ref) throws InterruptedException { final AtomicBoolean readyToAccept = new AtomicBoolean(false); final Runnable runner = new Runnable() { @Override public void run() { try { startUdtServer(serverAddress, ref, readyToAccept); } catch (final IOException e) { e.printStackTrace(); } } }; final Thread t = new Thread(runner, "test-thread"); t.setDaemon(true); t.start(); // We need to wait for a second to make sure the server thread starts. synchronized (readyToAccept) { if (!readyToAccept.get()) { readyToAccept.wait(4000); } } assertTrue("Not ready to accept?", readyToAccept.get()); Thread.yield(); Thread.yield(); Thread.yield(); Thread.yield(); } private void startUdtServer(final InetSocketAddress serverAddress, final AtomicReference<String> ref, final AtomicBoolean readyToAccept) throws IOException { final ServerSocket acceptorSocket = new NetServerSocketUDT(); acceptorSocket.bind(serverAddress); assert acceptorSocket.isBound(); readyToAccept.set(true); synchronized (readyToAccept) { readyToAccept.notifyAll(); } final Socket connectorSocket = acceptorSocket.accept(); assert connectorSocket.isConnected(); echo(connectorSocket, ref); } private void echo(final Socket socket, final AtomicReference<String> ref) throws IOException { final InputStream is = socket.getInputStream(); final OutputStream os = socket.getOutputStream(); final byte[] data = new byte[8192]; final Runnable runner = new Runnable() { @Override public void run() { try { final int count = is.read(data); final String str = new String(data, 0, count); log.info("|{}|", str); ref.set(str); os.write(str.getBytes()); synchronized (ref) { ref.notifyAll(); } } catch (final IOException e) { e.printStackTrace(); } } }; final Thread dt = new Thread(runner, "### starter"); dt.setDaemon(true); dt.start(); } }