Rev 216 | Blame | Compare with Previous | Last modification | View Log | RSS feed
/*******************************************************************************
* File: P2_Server.java
* Author: Ira W. Snyder (devel@irasnyder.com)
* License: GNU General Public License v2
* Class: CS380 - Computer Networking
*
* Assignment: Project #2
* Date Last Modified: 2006-02-08
*
* Purpose: Implement a simple server which will listen on UDP port 1337 for
* incoming datagrams. It will first recieve a message telling it to drop
* every n-th message. After that it will convert every message it recieves
* from 4B to 5B encoding, and reply back to the client. It will only exit on
* receiving the message "QUIT".
******************************************************************************/
import java.io.*;
import java.util.*;
import java.net.*;
import java.util.regex.*;
public class P2_Server
{
private static int portNumber = 1337;
private static int dropEvery = -1;
private static boolean dropPacket = false;
private static DatagramPacket packet;
private static DatagramSocket socket;
/**
* Method: readPacket()
* Purpose: Read a packet from the currently opened socket.
* Note: Blocks until it recieves data.
*/
public static P2_Packet readPacket ()
{
byte[] buf = new byte[256];
packet = new DatagramPacket (buf, buf.length);
// Try to recieve data from the client. Catch any
// exceptions that may occur.
try {
socket.receive (packet);
} catch (IllegalArgumentException e) {
System.err.println ("Caught exception in readPacket()");
e.printStackTrace ();
} catch (IOException e) {
System.err.println ("Caught exception in readPacket()");
e.printStackTrace ();
return null;
}
// Convert the packet, and print a status message.
P2_Packet ret = new P2_Packet (packet.getData());
System.out.printf ("Recieved a packet: %d bytes -- packetNum: %d\n",
ret.getPacketDataSize(), ret.getPacketNumber());
return ret;
}
/**
* Method: writePacket()
* Purpose: Write a message to the last client that sent us a message.
*/
public static boolean writePacket (byte type, byte[] data)
{
// Get the address and port of the last message sent to us.
InetAddress address = packet.getAddress();
int port = packet.getPort();
// Set up our packet
byte[] buf = P2_Packet.createPacket (type, data);
packet = new DatagramPacket (buf, buf.length, address, port);
// Attempt to send the packet
try {
socket.send (packet);
} catch (IOException e) {
System.out.println ("Caught exception in writePacket()");
e.printStackTrace();
return false;
}
// It got sent ok
return true;
}
/**
* Method: writePacket()
* Purpose: A simplified version of writePacket() above.
*/
public static boolean writePacket (byte type)
{
byte[] pData = { 0 };
return writePacket (type, pData);
}
/**
* Method: calcDropNum()
* Purpose: Parse a message sent by the client telling us to drop
* every n-th message.
*/
public static int calcDropNum (P2_Packet p)
{
if (p.getPacketType() != P2_Packet.DROP)
throw new IllegalArgumentException(); // major problem
// The byte informing us how often to drop packets is in
// the first byte only.
byte[] num = p.getPacketData();
return (int)num[0];
}
/**
* Method: main()
* Purpose: Open a listening UDP socket, and convert a client's
* requests from 4B encoding to 5B encoding.
*/
public static void main (String[] args) throws Exception
{
boolean done = false, droppedLast = false;
socket = new DatagramSocket(portNumber);
packet = null;
String s;
P2_Packet decodedPacket = null;
byte[] pData;
// Try to get a "timeout info" packet
while (!done)
{
decodedPacket = readPacket ();
dropEvery = calcDropNum (decodedPacket);
if (dropEvery != -1)
{
done = true;
System.out.println ("dropEvery: " + dropEvery);
}
writePacket (P2_Packet.DROP);
}
done = false;
// Keep reading until we get a quit packet
while (!done)
{
decodedPacket = readPacket ();
// Drop a packet if it is the correct time to do so
if ((decodedPacket.getPacketNumber() == dropEvery) && !droppedLast)
{
System.out.println ("Purposely dropped a packet");
droppedLast = true;
continue;
}
droppedLast = false;
// Figure out what type of packet to send in reply
switch (decodedPacket.getPacketType())
{
case P2_Packet.TRANSREQ:
try {
pData = P2_EncDec.convert4B (decodedPacket.getPacketData());
writePacket (P2_Packet.TRANSREPL, pData);
} catch (IllegalArgumentException e) {
System.err.println ("Received a bad packet");
writePacket (P2_Packet.BADPACKET);
}
break;
case P2_Packet.QUIT:
writePacket (P2_Packet.QUIT);
done = true;
break;
default:
System.err.println ("Got a packetType that I was not "
+ "expecting here.");
writePacket (P2_Packet.BADPACKET);
break;
}
}
// Close the socket
socket.close();
}
}