// Java Applet Demonstration of Go-Back-N Protocol.
// Coded by gongbo ID: 01091251
// Course No. EEE-459/591. Spring 2012
import java.applet.Applet;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class gbn extends Applet implements ActionListener, Runnable
{
final int window_len_def=5; // Default values of parameters
final int pack_width_def=10;
final int pack_height_def=30;
final int h_offset_def=100;
final int v_offset_def=50;
final int v_clearance_def=300;
final int total_packet_def=20;
final int time_out_sec_def= 30;
final Color unack_color= Color.red; // Default colors of different packets
final Color ack_color= Color.yellow;
final Color sel_color= Color.green;
final Color roam_pack_color= Color.red;
final Color roam_ack_color= Color.yellow;
final Color dest_color= Color.blue;
int base, nextseq, fps, selected=-1;
boolean timerFlag, timerSleep;
Button send, stop, fast, slow, kill, reset;
Thread gbnThread, timerThread;
Dimension offDimension; // flashing eliminator: double buffering
Image offImage;
Graphics offGraphics;
String statusMsg, strCurrentValues;
packet sender[];
// Declaring properties
int window_len, pack_width, pack_height, h_offset, v_offset, v_clearance,
total_packet, time_out_sec;
public void init()
{
String strWinLen, strPackWd, strPackHt, strHrOff, strVtOff, strVtClr, strTotPack, strTimeout;
strWinLen= getParameter("window_length"); // Start collecting parameters
strPackWd= getParameter("packet_width");
strPackHt= getParameter("packet_height");
strHrOff= getParameter("horizontal_offset");
strVtOff= getParameter("vertical_offset");
strVtClr= getParameter("vertical_clearance");
strTotPack= getParameter("total_packets");
strTimeout= getParameter("timer_time_out");
// Get the values of the parameters into properties.
try {
if (strWinLen != null) window_len= Integer.parseInt(strWinLen);
if (strPackWd != null) pack_width= Integer.parseInt(strPackWd);
if (strPackHt != null) pack_height= Integer.parseInt(strPackHt);
if (strHrOff != null) h_offset= Integer.parseInt(strHrOff);
if (strVtOff != null) v_offset= Integer.parseInt(strVtOff);
if (strVtClr != null) v_clearance= Integer.parseInt(strVtClr);
if (strTotPack != null) total_packet= Integer.parseInt(strTotPack);
if (strTimeout != null) time_out_sec= Integer.parseInt(strTimeout);
} catch (Exception e) {}
// If parameter is not found, use default values.
window_len= (window_len > 0) ? window_len : window_len_def;
pack_width= (pack_width > 0) ?pack_width : pack_width_def;
pack_height= (pack_height > 0) ? pack_height : pack_height_def;
h_offset= (h_offset > 0) ?h_offset : h_offset_def;
v_offset= (v_offset > 0) ?v_offset : v_offset_def;
v_clearance= (v_clearance > 0) ? v_clearance : v_clearance_def;
total_packet= (total_packet > 0) ? total_packet : total_packet_def;
time_out_sec= (time_out_sec > 0) ? time_out_sec : time_out_sec_def;
base= 0;// Defining base
nextseq= 0;// Defining Next sequence number.
fps= 5;// Defining default Frame per Second.
sender= new packet[total_packet];
statusMsg= "Ready to run. Press 'Send New' button to start.";
strCurrentValues= "Window Base= "+ base +".Next Sequence No.= "+ nextseq;
// Defining the buttons
send= new Button("Send New");
send.setActionCommand("rdt");
send.addActionListener(this);
stop= new Button("Stop Animation");
stop.setActionCommand("stopanim");
stop.addActionListener(this);
fast= new Button("Faster");
fast.setActionCommand("fast");
fast.addActionListener(this);
slow= new Button("Slower");
slow.setActionCommand("slow");
slow.addActionListener(this);
kill= new Button("Kill Packet");
kill.setActionCommand("kl");
kill.addActionListener(this);
kill.setEnabled(false);
reset= new Button("Reset");
reset.setActionCommand("rst");
reset.addActionListener(this);
// Adding the buttons
add(send);
add(stop);
add(fast);
add(slow);
add(kill);
add(reset);
}
public void start() {
if (gbnThread==null) // Creating main thread and start it
gbnThread= new Thread(this);
gbnThread.start();
}
public void run() {
Thread currenthread= Thread.currentThread();
while (currenthread==gbnThread) // While the animation is running
if (onTheWay(sender)) // Checks if any of the packets are travelling
{
for (int i=0; i<total_packet; i++)
if (sender[i]!= null)
if (sender[i].on_way) // If packet is roaming
if (sender[i].packet_pos < (v_clearance-pack_height))
sender[i].packet_pos+=5; // Move packet
else if (sender[i].packet_ack) // If it is moving to destination {
sender[i].reached_dest= true;
if (check_upto_n(i)) // Send acknowledgement if all preceeding
{
// packets are received.
sender[i].packet_pos= pack_height+5;
sender[i].packet_ack= false;
statusMsg= "Packet "+i+" received. Acknowledge sent.";
}
else
{ sender[i].on_way= false;
statusMsg= "Packet "+i+" received. No acknowledge sent.";
if (i==selected)
{ selected= -1;
kill.setEnabled(false);
}
}
}
else if (!sender[i].packet_ack) // acknowledgement
{
statusMsg= "Packet "+ i +" acknowledge received.";
sender[i].on_way= false;
for (int n=0; n<=i; n++)
sender[n].acknowledged= true;
if (i==selected) {
selected= -1; kill.setEnabled(false);
}
timerThread= null; //resetting timer thread
if (i+window_len<total_packet)
base= i+1;
if (nextseq < base+window_len) send.setEnabled(true);
if (base != nextseq)
{
statusMsg += " Timer restarted.";
timerThread= new Thread(this);
timerSleep= true;
timerThread.start();
}
else
statusMsg += " Timer stopped.";
}
strCurrentValues= "Window Base= "+ base +". Next Sequence No.= "+ nextseq;
repaint();
try {
Thread.sleep(1000/fps);
}
catch (InterruptedException e) {
System.out.println("Help");
}
}
else
gbnThread= null;
while (currenthread== timerThread)
if (timerSleep) {
timerSleep=false;
try {
Thread.sleep(time_out_sec*1000);
}
catch (InterruptedException e)
{
System.out.println ("Timer interrupted.");
}
}
else {
for (int n=base; n<base+window_len; n++)
if (sender[n] != null)
if (!sender[n].acknowledged)
{ sender[n].on_way= true;
sender[n].packet_ack= true;
sender[n].packet_pos= pack_height+5;
}
timerSleep= true;
if (gbnThread== null) {
gbnThread= new Thread (this);
gbnThread.start();
}
statusMsg= "Packets resent by timer. Timer restarted."; }
}
public void actionPerformed(ActionEvent e) {
String cmd= e.getActionCommand();
if (cmd== "rdt" && nextseq < base+window_len) // Send button is pressed
{ sender[nextseq]= new packet(true,pack_height+5);
statusMsg= "Packet "+ nextseq +" sent.";
if (base== nextseq) { // i.e. the window is empty and a new data is getting in
st