119 lines
3.7 KiB
Java
119 lines
3.7 KiB
Java
|
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;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|