用java Applet实现网络传输的gbn(退步重传)


//  Coded by Shamiul Azom. ASU ID: 993456298
//  as project assigned by Prof. Martin Reisslein, Arizona State University
//  Course No. EEE-459/591. Spring 2001


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
    statusMsg += " Timer set for packet "+ base +".";
    
if (timerThread == null)
     timerThread 
= new Thread(this);
    timerSleep 
= true;
    timerThread.start();
    }


   repaint();
   nextseq
++;
   
if (nextseq == base+window_len)
    send.setEnabled(
false);
   start();
   }


  
else if (cmd == "fast")    // Faster button pressed
   {
   fps
+=2;
   statusMsg 
= "Simulation speed increased by 2 fps.";
   }


  
else if (cmd == "slow" && fps>2)
   
{
   fps
-=2;
   statusMsg 
= "Simulation speed decreased by 2 fps.";
   }


  
else if (cmd == "stopanim")
   
{
   gbnThread 
= null;
   
if (timerThread != null)
    
{
    timerFlag 
= true;
    timerThread 
= null;   // added later
    }

   stop.setLabel(
"Resume");
   stop.setActionCommand(
"startanim");

   
// disableing all the buttons
   send.setEnabled(false);
   slow.setEnabled(
false);
   fast.setEnabled(
false);
   kill.setEnabled(
false);

   statusMsg 
= "Simulation paused.";
   repaint();
   }


  
else if (cmd == "startanim")
   
{
   statusMsg 
= "Simulation resumed.";
   stop.setLabel(
"Stop Animation");
   stop.setActionCommand(
"stopanim");
   
if (timerFlag)
    
{
    statusMsg 
+= " Timer running.";
    timerThread 
= new Thread(this);
    timerSleep 
= true;
    timerThread.start();
    }


   
// enabling the buttons
   send.setEnabled(true);
   slow.setEnabled(
true);
   fast.setEnabled(
true);
   kill.setEnabled(
true);
   repaint();    
// repainted to show new messages

   start();
   }


  
else if (cmd == "kl")
   
{
   
if (sender[selected].packet_ack)
    statusMsg 
= "Packet "+ selected +" destroyed. Timer running for packet "+base+".";
   
else
    statusMsg 
= "Acknowledgement of packet "+ selected +" destroyed. Timer running for packet "+base+".";

   sender[selected].on_way 
= false;
   kill.setEnabled(
false);
   selected 
= -1;
   repaint();
   }


  
else if (cmd == "rst")
   reset_app();
  }


 
public boolean mouseDown(Event e, int x, int y)
  
{
  
int i, xpos, ypos;
  i 
= (x-h_offset)/(pack_width+7);
  
if (sender[i]!= null)
   
{
   xpos 
= h_offset+(pack_width+7)*i;
   ypos 
= sender[i].packet_pos;

   
if (x>=xpos && x<= xpos+pack_width && sender[i].on_way)
    
{
    
if ((sender[i].packet_ack && y>=v_offset+ypos &&
y
<=v_offset+ypos+pack_height) || ((!sender[i].packet_ack) &&
y
>=v_offset+v_clearance-ypos && y<=v_offset+v_clearance-ypos+pack_height))
     
{
     statusMsg 
= "Packet "+ i +" selected.";
     sender[i].selected 
= true;
     selected 
= i;
     kill.setEnabled(
true);
     }

    
else
     statusMsg 
= "Click on a moving packet to select.";
    }

   
else
    statusMsg 
= "Click on a moving packet to select.";
   }

  
return true;
  }


 
public void paint(Graphics g)    // To eliminate flushing, update is overriden
  {
  update(g);
  }



 
public void update(Graphics g)
  
{
  Dimension d 
= size();

  
//Create the offscreen graphics context, if no good one exists.
        if ((offGraphics == null|| (d.width != offDimension.width) ||
(d.height 
!= offDimension.height))
   
{
            offDimension 
= d;
            offImage 
= createImage(d.width, d.height);
            offGraphics 
= offImage.getGraphics();
   }


  
//Erase the previous image.
        offGraphics.setColor(Color.white);
        offGraphics.fillRect(
00, d.width, d.height);

  
//drawing window


  offGraphics.setColor(Color.black);
  offGraphics.draw3DRect(h_offset
+base*(pack_width+7)-4, v_offset-3,
(window_len)
*(pack_width+7)+1, pack_height+6,true);


  
for (int i=0; i<total_packet; i++)
   
{
   
// drawing the sending row

   
if (sender[i]==null)
    
{
    offGraphics.setColor(Color.black);
    offGraphics.draw3DRect(h_offset
+(pack_width+7)*i, v_offset,
pack_width,pack_height,
true);
    offGraphics.draw3DRect(h_offset
+(pack_width+7)*i, v_offset+v_clearance,
pack_width,pack_height,
true);
    }

   
else
    
{
    
if (sender[i].acknowledged)
     offGraphics.setColor(ack_color);
    
else
     offGraphics.setColor(unack_color);
    offGraphics.fill3DRect (h_offset
+(pack_width+7)*i,
v_offset,pack_width,pack_height,
true);


    
// drawing the destination packets

    offGraphics.setColor (dest_color);
    
if (sender[i].reached_dest)
     offGraphics.fill3DRect (h_offset
+(pack_width+7)*i,
v_offset
+v_clearance,pack_width,pack_height,true);
    
else
     offGraphics.draw3DRect (h_offset
+(pack_width+7)*i,
v_offset
+v_clearance,pack_width,pack_height,true);

    
// drawing the moving packets

    
if (sender[i].on_way)
     
{
     
if (i==selected)
      offGraphics.setColor (sel_color);
     
else if (sender[i].packet_ack)
      offGraphics.setColor (roam_pack_color);
     
else
      offGraphics.setColor (roam_ack_color);

     
if (sender[i].packet_ack)
      offGraphics.fill3DRect (h_offset
+(pack_width+7)*i,
v_offset
+sender[i].packet_pos,pack_width,pack_height,true);
     
else
      offGraphics.fill3DRect (h_offset
+(pack_width+7)*i,
v_offset
+v_clearance-sender[i].packet_pos,pack_width,pack_height,true);
     }

    }

   }
   // for loop ends

   
// drawing message boxes

   offGraphics.setColor(Color.black);
   
int newvOffset = v_offset+v_clearance+pack_height;
   
int newHOffset = h_offset;

   offGraphics.drawString(statusMsg,newHOffset,newvOffset
+25);
   
//offGraphics.drawString(strCurrentValues,newHOffset,newvOffset+40);

   offGraphics.drawString(
"Packet",newHOffset+15,newvOffset+60);
   offGraphics.drawString(
"Acknowledge",newHOffset+85,newvOffset+60);
   offGraphics.drawString(
"Received Pack",newHOffset+185,newvOffset+60);
   offGraphics.drawString(
"Selected",newHOffset+295,newvOffset+60);

   offGraphics.drawString(
"Base = "+base,h_offset+(pack_width+7)*total_packet+10,v_offset+v_clearance/2);
   offGraphics.drawString(
"NextSeq = "+nextseq,h_offset+(pack_width+7)*total_packet+10,v_offset+v_clearance/2+20);

   offGraphics.setColor(Color.blue);

offGraphics.drawString(
"Sender",h_offset+(pack_width+7)*total_packet+10,v_offset+12);


offGraphics.drawString(
"Receiver",h_offset+(pack_width+7)*total_packet+10,v_offset+v_clearance+12);


   offGraphics.setColor(Color.gray);
   offGraphics.draw3DRect(newHOffset
-10,newvOffset+42,360,25,true);

   offGraphics.setColor(Color.red);

offGraphics.draw3DRect(h_offset
+(pack_width+7)*total_packet+5,v_offset+v_clearance/2-15,80,40,true);


   offGraphics.setColor(roam_pack_color);
   offGraphics.fill3DRect(newHOffset, newvOffset
+50,10,10,true);

   offGraphics.setColor(roam_ack_color);
   offGraphics.fill3DRect(newHOffset
+70, newvOffset+50,10,10,true);

   offGraphics.setColor(dest_color);
   offGraphics.fill3DRect(newHOffset
+170, newvOffset+50,10,10,true);

   offGraphics.setColor(sel_color);
   offGraphics.fill3DRect(newHOffset
+280, newvOffset+50,10,10,true);


  g.drawImage(offImage, 
00this);
  }
    // method paint ends


 
// checks out if an array is on the way to source or destination

 
public boolean onTheWay(packet pac[])
  
{
  
for (int i=0; i<pac.length; i++)
   
if (pac[i] == null)
    
return false;
   
else if (pac[i].on_way) return true;
  
return false;
  }


 
// checkes all the packets before packno. Returns false if any packet has
 
// not reached destination and true if all the packets have reached destination.

 
public boolean check_upto_n(int packno)
  
{
  
for (int i=0; i<packno; i++)
   
if (!sender[i].reached_dest)
    
return false;
  
return true;
  }


 
public void reset_app()
  
{
  
for (int i=0; i<total_packet; i++)
   
if (sender[i] != null)
    sender[i] 
= null;
  base 
= 0;
  nextseq 
= 0;
  selected 
= -1;
  fps 
= 5;
  timerFlag 
= false;
  timerSleep 
= false;
  gbnThread 
= null;
  timerThread 
= null;
  
if(stop.getActionCommand()=="startanim")  // in case of pause mode, enable all buttons
   {
   slow.setEnabled(
true);
   fast.setEnabled(
true);
   }


  send.setEnabled(
true);
  kill.setEnabled(
false);

  stop.setLabel(
"Stop Animation");
  stop.setActionCommand(
"stopanim");
  statusMsg 
= "Simulation restarted. Press 'Send New' to start.";
  repaint();
  }

 }


class  packet
 
{
 
boolean on_way, reached_dest, acknowledged, packet_ack, selected;
 
int packet_pos;

 packet()
  
{
  on_way 
= false;
  selected 
= false;
  reached_dest 
= false;
  acknowledged 
= false;
  packet_ack 
= true;
  packet_pos 
= 0;
  }


 packet(
boolean onway, int packetpos)
  
{
  on_way 
= onway;
  selected 
= false;
  reached_dest 
= false;
  acknowledged 
= false;
  packet_ack 
= true;
  packet_pos 
= packetpos;
  }

 }

 

你可能感兴趣的:(用java Applet实现网络传输的gbn(退步重传))