package at.uniklu.itec.rechnernetze.udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.LinkedList;
/**
* REP Rechnernetze, SS 2007
* (c) 2007 by Mathias Lux
*/
public class CaesarServer implements Runnable {
private static final byte CAESAR_KEY = 13;
protected static final int MTU = 1024;
DatagramSocket socket;
CaesarServerListener listener;
private DatagramPacket pack = null;
private int responsePort;
private InetAddress responseAddress;
private LinkedList<DatagramPacket> workload;
/**
* Creates a new CeasarServer on the specified port
* @param port the port for the server.
* @throws SocketException in case of socket errors.
*/
public CaesarServer(int port) throws SocketException {
workload = new LinkedList<DatagramPacket>();
socket = new DatagramSocket(port);
System.out.println("Socket created on port " + socket.getLocalPort());
listener = new CaesarServerListener(socket, workload);
}
/**
* The actual start of the server.
*/
public void run() {
listener.start();
synchronized(workload){
try {
while(true){
System.out.println("Hallo, ich bin in CS..");
workload.wait();
}
}
catch (InterruptedException e) {
}
finally{
pack = workload.removeFirst();
System.out.println("HELLO!!");
}
}
pack = workload.removeFirst();
System.out.println("HELLO!!");
System.out.println("Packet taken from Queue..");
responsePort = pack.getPort();
responseAddress = pack.getAddress();
byte[] retVal = new byte[MTU];
if(pack.getData()[0] == 0){
retVal = decode(pack.getData(), 1, MTU);
}
else if(pack.getData()[0] == 1){
retVal = encode(pack.getData(), 1, MTU);
}
pack.setData(retVal);
pack.setAddress(responseAddress);
pack.setPort(responsePort);
try{
socket.send(pack);
}
catch(Exception e){
e.printStackTrace();
}
// * functionality for getting new packets from workload, en-/decoding them and sending the results back
}
private static byte[] encode(byte[] data, int offset, int length) {
for (int i = offset; i < Math.min(offset + length, data.length); i++) {
data[i] = (byte) (data[i] + CAESAR_KEY);
}
return data;
}
private static byte[] decode(byte[] data, int offset, int length) {
for (int i = offset; i < Math.min(offset + length, data.length); i++) {
data[i] = (byte) (data[i] - CAESAR_KEY);
}
System.out.println(data.toString());
return data;
}
/**
* Main method for testing
* @param args command line arguments.
* @throws IOException in case of problems with the socket.
*/
public static void main(String[] args) throws IOException {
int port = 23456;
port = parseArguments(args);
if (0 < port && port < 65536) {
CaesarServer server = new CaesarServer(port);
server.run();
} else {
System.err.println("Port number has to be given! " + port + " is not a valid port number!");
printUsage();
System.exit(1);
}
}
/**
* Helper method for parsing the command line arguments.
* @param args command line arguments.
* @return the parsed port.
*/
private static int parseArguments(String[] args) {
int port = -1;
for (int i = 0; i < args.length; i++) {
String s = args[i];
if (s.startsWith("-p") || s.startsWith("--port")) {
// this is the port parameter
try {
port = Integer.parseInt(args[i + 1]);
} catch (NumberFormatException e) {
System.err.println("Port number has to be given! " + args[i + 1] + " is not a valid port number!");
printUsage();
System.exit(1);
}
}
if (s.startsWith("-h") || s.startsWith("--help")) {
printUsage();
System.exit(1);
}
}
return port;
}
/**
* Help message for starting the server.
*/
private static void printUsage() {
String help = "java at.uniklu.itec.rechnernetze.udp.CaesarServer -p <port> [-h]\n" +
"\t-p ... Setting the port where the server listens\n" +
"\t-h ... prints this message";
System.out.println(help);
}
}
/**
* Thread which waits for new packets coming in from the socket
* and puts them into the workload list.
*/
class CaesarServerListener implements Runnable {
DatagramSocket socket;
private LinkedList<DatagramPacket> workload;
public CaesarServerListener(DatagramSocket socket, LinkedList<DatagramPacket> workload) {
this.socket = socket;
this.workload = workload;
}
public void run() {
System.out.println("CasearServerListener started on port " + socket.getLocalPort());
try{
while(true){
DatagramPacket pack = new DatagramPacket(new byte[1024], 1024);
socket.receive(pack);
System.out.println("New Packet added to queue..");
synchronized(workload){
workload.add(pack);
workload.notifyAll();
}
}
}
catch (IOException e){
e.printStackTrace();
}
// TODO:
// * Listen for new packets and put them into workload as soon as they arrive.
}
}