package transport; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketException; import java.util.Random; public abstract class Transport implements Runnable { private DatagramSocket socket = null; private DatagramPacket rcv_packet = null; private DatagramPacket snd_packet = null; private static Random generator = new Random(); private double error = 0.0D; private boolean disconnect_allowed = true; private MyTimer timer = new MyTimer(this); private Thread listener; public static final int MAX_PACKET_SIZE = 1024; public static final int END_OF_STREAM = -1; public Transport() { } public final synchronized void connect(int var1, InetAddress var2, int var3) throws IllegalArgumentException, SocketException { this.socket = new DatagramSocket(new InetSocketAddress(var1)); this.socket.connect(var2, var3); this.socket.setSoTimeout(60000); if (this.snd_packet == null) { this.snd_packet = new DatagramPacket(new byte[1024], 1024, var2, var3); } else { this.snd_packet.setAddress(var2); this.snd_packet.setPort(var3); } if (this.rcv_packet == null) { this.rcv_packet = new DatagramPacket(new byte[1024], 1024); } if (this.listener == null) { this.listener = new Thread(this); this.listener.setDaemon(true); this.listener.start(); } } protected final synchronized void allowDisconnect() { this.disconnect_allowed = true; this.notifyAll(); } protected final synchronized void blockDisconnect() { this.disconnect_allowed = false; } public final synchronized void disconnect() throws InterruptedException { while(!this.disconnect_allowed) { this.wait(); } if (this.socket != null) { this.socket.close(); this.listener.interrupt(); this.socket = null; this.listener = null; this.timer.stop(); } } protected abstract void unreliableReceive(byte[] var1, int var2, int var3); protected final void unreliableSend(byte[] var1, int var2, int var3) { if (generator.nextDouble() >= this.error) { try { this.snd_packet.setData(var1, var2, var3); this.socket.send(this.snd_packet); } catch (Exception var5) { System.err.println("unreliableSend: error sending packet: " + var5); var5.printStackTrace(); } } } public final void setErrorPercentage(double var1) { this.error = var1 / 100.0D; } public final synchronized void setTimeout(long var1, TimeoutAction var3) { this.timer.schedule(var3, var1); } public final synchronized void cancelTimeout(TimeoutAction var1) { this.timer.cancel(var1); } public final void run() { while(this.socket != null) { try { this.socket.receive(this.rcv_packet); synchronized(this) { this.unreliableReceive(this.rcv_packet.getData(), this.rcv_packet.getOffset(), this.rcv_packet.getLength()); } } catch (IOException var6) { synchronized(this) { if (this.socket == null) { return; } } System.err.println("run: error receiving data from the network: " + var6); System.err.println("Terminating."); return; } } } }