package org.mobicents.media.server.impl.rtp; /* * To change this template, choose Tools | Templates * and open the template in the editor. */ //package org.mobicents.media.server.impl.rtp; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; import java.net.SocketException; import java.nio.ByteBuffer; import java.nio.channels.DatagramChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.util.ArrayList; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; /** * * @author kulikov * * */ public class TestNio { // Pool for signalling private static transient ExecutorService pool = Executors.newFixedThreadPool(10, new ThreadFactoryImpl()); private static ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor(); private Thread worker; private volatile boolean started = false; private static String mcAddress = "127.0.0.1"; public static void main(String[] args) throws Exception { TestNio t = new TestNio(); t.doTest(); } public void doTest() throws Exception { int N = 250; started = true; Receiver r = new Receiver(); Server1[] servers = new Server1[N]; for (int i = 0; i < N; i++) { servers[i] = new Server1(i); r.add(servers[i]); } // (new Thread(new Signal())).start(); System.out.println("Servers are ready "); worker = new Thread(r); worker.start(); Client1[] clients = new Client1[N]; for (int i = 0; i < N; i++) { clients[i] = new Client1(i); timer.scheduleAtFixedRate(clients[i], 0, 20, TimeUnit.MILLISECONDS); } Thread.currentThread().sleep(1000 * 60 * 1); timer.shutdown(); started = false; pool.shutdown(); for (int i = 0; i < N; i++) { servers[i].stop(); } clients[50].printTicks(); System.out.println("==============================="); servers[50].printTicks(); } private class Client implements Runnable { private DatagramSocket socket; private InetSocketAddress destination; private ArrayList<Long> ticks = new ArrayList(5000); public Client(int index) throws SocketException { int port = 8000 + index; InetSocketAddress address = new InetSocketAddress(mcAddress, port); destination = new InetSocketAddress(mcAddress, port - 2000); socket = new DatagramSocket(address); } public void run() { byte[] buffer = new byte[160]; try { DatagramPacket p = new DatagramPacket(buffer, buffer.length, destination); for (int i = 0; i < 160; i++) { buffer[i] = (byte) (100 * 2 + 20 / 10 + 40 / 2 + 20 * 10); } socket.send(p); ticks.add(System.currentTimeMillis()); } catch (IOException e) { e.printStackTrace(); } } public void printTicks() { System.out.println("Packets " + ticks.size()); for (int i = 1; i < ticks.size(); i++) { System.out.println("Client diff for index = " + i + " =" + (ticks.get(i) - ticks.get(i - 1))); } } } private class Client1 implements Runnable { private DatagramChannel channel; private ByteBuffer buffer = ByteBuffer.allocate(160); private ArrayList<Long> ticks = new ArrayList(5000); private InetSocketAddress destination; public Client1(int index) throws SocketException, java.io.IOException { int port = 8000 + index; InetSocketAddress address = new InetSocketAddress(mcAddress, port); destination = new InetSocketAddress(mcAddress, port - 2000); channel = DatagramChannel.open(); channel.socket().bind(address); channel.connect(destination); channel.configureBlocking(false); } public void run() { int len = 160; byte[] buffer = new byte[len]; try { for (int i = 0; i < len; i++) { buffer[i] = (byte) (100 * 2 + 20 / 10 + 40 / 2 + 20 * 10); } ByteBuffer buffer1 = ByteBuffer.wrap(buffer); int count = 0; // In loop to take care of async send operation while (count < len) { count = channel.send(buffer1, destination); if (count != 160) { System.out.println("BAD!BAD!BAD! " + count); } count += count; buffer1.compact(); buffer1.flip(); } ticks.add(System.currentTimeMillis()); } catch (IOException e) { e.printStackTrace(); } } public void printTicks() { System.out.println("Packets " + ticks.size()); for (int i = 1; i < ticks.size(); i++) { System.out.println("Client diff for index = " + i + " =" + (ticks.get(i) - ticks.get(i - 1))); } } } private class Server implements Runnable { private DatagramSocket socket; private boolean stopped = false; private ArrayList<Long> ticks = new ArrayList(5000); int port = 6000; public Server(int index) throws SocketException { port = port + index; InetSocketAddress address = new InetSocketAddress(mcAddress, port); socket = new DatagramSocket(address); new Thread(this).start(); } public void stop() { stopped = true; socket.close(); } public void run() { byte[] buffer = new byte[1000]; DatagramPacket packet = new DatagramPacket(buffer, 1000); System.out.println("Started server at port = " + port); while (!stopped) { try { socket.receive(packet); ticks.add(System.currentTimeMillis()); } catch (IOException e) { } } } public void printTicks() { // for (int i = 1; i < ticks.size(); i++) { // System.out.println("diff =" + (ticks.get(i) - ticks.get(i - 1))); // } System.out.println("Packets " + ticks.size()); long diff; long jitter = 0; for (int i = 1; i < ticks.size(); i++) { diff = (ticks.get(i) - ticks.get(i - 1)); System.out.println("Server diff for index = " + i + " = " + diff); jitter = jitter + (diff - 20); } System.out.println("Jitter avg = " + jitter); } } private class Receiver implements Runnable { private ArrayList<Server1> list = new ArrayList(); public void add(Server1 s) { list.add(s); } public void run() { System.out.println("Worker started: " + list.size() + " started = " + started); while (started) { for (Server1 receiver : list) { receiver.run(); } try { Thread.currentThread().sleep(20); } catch (InterruptedException e) { } } System.out.println("Worker terminated"); } } private class Signal implements Runnable { int newSignalThreads = 3; private int index = 0; public void run() { while (started) { for (int i = 0; i < newSignalThreads; i++) { Runnable task = new Runnable() { public void run() { index = index + 1; try { double randNumber = Math.random(); double sqrt = Math.sqrt(randNumber); System.out.println("Signalling done for index = " + index + " randNumber = " + randNumber + " sqrt = " + sqrt); } catch (Exception e) { } } }; pool.submit(task); }// end of for loop try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }// end of whil loop System.out.println("Signal Thread terminated"); } } private class Server1 implements Runnable { private DatagramChannel channel; private ByteBuffer buffer = ByteBuffer.allocate(1000); private ArrayList<Long> ticks = new ArrayList(5000); private Selector selector; public Server1(int index) throws SocketException, IOException { int port = 6000 + index; InetSocketAddress address = new InetSocketAddress(mcAddress, port); channel = DatagramChannel.open(); System.out.println("Channel is open " + index); channel.socket().bind(address); System.out.println("Socket is bound to " + address); channel.connect(new InetSocketAddress(mcAddress, port + 2000)); System.out.println("Socket is connected to port " + (port + 2000)); selector = Selector.open(); channel.configureBlocking(false); System.out.println("Selected opened"); channel.register(selector, SelectionKey.OP_READ); System.out.println("Selected - 0"); } public void stop() throws IOException { selector.close(); channel.disconnect(); channel.close(); channel.socket().close(); } public void run() { try { // selector.select(); int count = channel.read(buffer); if (count != 160) { System.out.println("BAD!BAD!BAD!BAD! " + count); } buffer.flip(); buffer.clear(); if (count > 0) { ticks.add(System.currentTimeMillis()); } } catch (Exception e) { e.printStackTrace(); } } public void printTicks() { System.out.println("Packets " + ticks.size()); long diff; long jitter = 0; for (int i = 1; i < ticks.size(); i++) { diff = (ticks.get(i) - ticks.get(i - 1)); System.out.println("diff =" + diff); jitter = jitter + (diff - 20); } System.out.println("Jitter avg = " + jitter); } } static class ThreadFactoryImpl implements ThreadFactory { final ThreadGroup group; static final AtomicInteger msProviderPoolNumber = new AtomicInteger(1); final AtomicInteger threadNumber = new AtomicInteger(1); final String namePrefix; ThreadFactoryImpl() { SecurityManager s = System.getSecurityManager(); group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); namePrefix = "MsProviderImpl-FixedThreadPool-" + msProviderPoolNumber.getAndIncrement() + "-thread-"; } public Thread newThread(Runnable r) { Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0); if (t.isDaemon()) { t.setDaemon(false); } if (t.getPriority() != Thread.MIN_PRIORITY) { t.setPriority(Thread.MIN_PRIORITY); } return t; } } }