package com.jotuntech.sketcher.server; import java.io.IOException; import java.net.DatagramSocket; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.nio.ByteBuffer; import java.nio.channels.DatagramChannel; import java.util.HashMap; public class VoiceServer extends Thread { public final static int SPEEX_FRAME_BYTES = 640; private HashMap clients = new HashMap(); ByteBuffer packetBuffer; int listenPort; public VoiceServer(int listenPort) { super("VoiceServer"); this.listenPort = listenPort; } public void run() { System.err.println("Voice server started."); packetBuffer = ByteBuffer.allocate(SPEEX_FRAME_BYTES + 8); DatagramChannel channel = null; try { channel = DatagramChannel.open(); channel.configureBlocking(true); DatagramSocket socket = channel.socket(); socket.bind(new InetSocketAddress(listenPort)); channel.configureBlocking(false); while(!interrupted()) { sleep(10); for(SocketAddress source = channel.receive(packetBuffer); source != null; source = channel.receive(packetBuffer)) { packetBuffer.flip(); Integer sourceKey = packetBuffer.getInt(0); /** Allow only familiar clients */ if(clients.containsKey(sourceKey)) { if(clients.get(sourceKey) == null || !clients.get(sourceKey).equals(source)) { /** Client is familiar but needs to be assigned an address */ clients.put(sourceKey, (InetSocketAddress) source); System.err.println("Assigning address " + source + " to client " + sourceKey); } synchronized(clients) { for(InetSocketAddress address : clients.values()) { if(address == null) { /** Send only to clients with assigned addresses */ continue; } if(address.equals(source)) { /** Send only to other clients than source of packet */ continue; } if(channel.send(packetBuffer, address) > 0) { packetBuffer.flip(); } else { System.err.println("Dropped packet."); } } } } packetBuffer.clear(); } } } catch(InterruptedException e) { } catch (IOException e) { e.printStackTrace(); } try { if(channel != null) { channel.close(); } } catch (IOException e) { e.printStackTrace(); } System.err.println("Voice server interrupted."); } public void addClient(Integer peerKey) { synchronized(clients) { clients.put(peerKey, null); } System.err.println("Added client " + peerKey); } public void removeClient(Integer peerKey) { synchronized(clients) { clients.remove(peerKey); } System.err.println("Removed client " + peerKey); } }