This repository has been archived on 2021-10-31. You can view files and clone it, but cannot push or open issues or pull requests.
NTW/hw2/src/transport/Transport.java

119 lines
3.7 KiB
Java
Raw Normal View History

2020-05-08 12:25:09 +00:00
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;
}
}
}
}