Computer Networks | Implementing Byte stuffing using Java


Need for Byte-Stuffing
In variable-size framing at the data link layer, we need to define a way to separate one frame from the next. Byte stuffing is employed to accomplish the task. In byte stuffing an 8-bit flag (‘F’) is added at the beginning and at the end of the frame, thereby distinguishing one frame from the next. Therefore, every time a flag sequence (‘F’) is encountered, it signifies the beginning or end of a frame. This, ingenious scheme, however would give rise to a discrepancy, if the flag pattern (‘F’) would occur within the data carried by the frame itself. Byte stuffing comes to the rescue here, by stuffing the original data with an extra 8-bit escape sequence (‘E’) before the flag pattern, whenever it occurred within the data carried by a frame. The receiver would then have to de-stuff the escape sequence, in order to obtain the original data.

A simple question that might arise at this juncture is, what if the escape sequence (‘E’) formed a part of the data to be sent! This scenario is handled in exactly the same way as described above, i.e an extra 8-bit escape sequence (‘E’) is added to the original data before the escape sequence that formed part of the data.

In character-oriented protocols, where data to be carried are 8-bit characters, byte stuffing is employed to handle the problems discussed above.

To make things simpler we will consider only three types of byte sequences in the sent data, as :
F : Flag Sequence
E : Escape Sequence
D : Any other Data Sequence

For Example :



At Sender Side
Enter the Message to be Sent : 
DDEDFFDE
The data being sent (with byte stuffed) is : FDDEEDEFEFDEEF
Seding Message....
Thanks for the Feedback Server!!

At Receiver Side
Message Recevied...Successfully!!!
The Stuffed Message is : FDDEEDEFEFDEEF
The Destuffed Message is : DDEDFFDE
Messaging is over.....EXITING

From the above example we can see how the original data is recovered at the receiver end.

Approach

At Sender (Client) Side

  1. Data of each frame at the sender side, is first stuffed with 8-bit flag sequence (‘F’) at the beginning and end of each frame.
  2. Next, the data is scanned to see if any similar flag sequence (‘F’) forms a part of it or not. If yes, then before each such flag sequence, an extra escape sequence (‘E’) is stuffed.
  3. Now, if any similar escape sequence (‘E’) is found to form a part of the data to be sent, then an extra escape sequence (‘E’) is stuffed before the occurrence of each such escape sequence.
  4. Finally, this stuffed data is sent by the sender.
  5. At Receiver (Server) Side

    1. The receiver skips over the first and last bytes of data received, as they are merely for signalling the beginning and end of one frame, respectively and does not carry any useful data.
    2. From the next byte on wards data is scanned and if two escape sequences (‘E’) are found in succession, the first one is de-stuffed. Similarly, if an escape sequence is followed by a flag sequence (‘F’), the former is de-stuffed.
    3. This strategy helps the receiver recover the actual sent data, accurately.
    4. Implementation

      At Sender (Client) Side

      filter_none

      edit
      close

      play_arrow

      link
      brightness_4
      code

      // Java Code for Byte_Stuffing Sender
      package byte_stuffing;
      import java.io.*;
      import java.util.*;
      import java.net.*;
        
      public class Byte_Stuffing_Client {
          public static void main(String args[]) throws IOException
          {
              InetAddress ip = InetAddress.getLocalHost();
              int port = 45678;
              Scanner sc = new Scanner(System.in);
        
              // Opens a socket for connection
              Socket s = new Socket(ip, port);
        
              // Declaring I/O Streams
              DataInputStream dis = new DataInputStream(s.getInputStream());
              DataOutputStream dos = new DataOutputStream(s.getOutputStream());
        
              while (true) {
                  System.out.println("Enter the Message to be Sent : ");
                  String data = sc.nextLine();
                  String res = new String();
        
                  // Data in each frame is stuffed by 'F' at beginning and end
                  data = 'F' + data + 'F';
                  for (int i = 0; i < data.length(); i++) {
        
                      // Stuff with 'E' if 'F' is found in the data to be sent
                      if (data.charAt(i) == 'F' && i != 0 && i != (data.length() - 1))
                          res = res + 'E' + data.charAt(i);
        
                      // Stuff with 'E' if 'E' is found in the data to be sent
                      else if (data.charAt(i) == 'E')
                          res = res + 'E' + data.charAt(i);
                      else
                          res = res + data.charAt(i);
                  }
        
                  System.out.println("The data being sent (with byte stuffed) is : " + res);
        
                  // Send the data to the receiver
                  dos.writeUTF(res);
                  System.out.println("Seding Message....");
                  if (dis.readUTF().equals("success"))
                      System.out.println("Thanks for the Feedback Server!!");
        
                  // End Messaging
                  dos.writeUTF("bye");
                  break;
              }
        
              // Close all connections
              s.close();
              dis.close();
              dos.close();
          }
      }

      chevron_right

      
      

      At Receiver (Server) Side

      filter_none

      edit
      close

      play_arrow

      link
      brightness_4
      code

      // Java code for Byte_Stuffing Receiver
      package byte_stuffing;
      import java.io.*;
      import java.net.*;
        
      public class Byte_Stuffing {
          public static void main(String[] args) throws IOException
          {
              // Opens a socket for connection
              ServerSocket servsock = new ServerSocket(45678);
        
              // Used to block until a client connects to the server
              Socket socket = servsock.accept();
        
              // Declaring I/O Streams
              DataInputStream dis = new DataInputStream(socket.getInputStream());
              DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
        
              while (true) {
                  String out = new String();
                  // Used to read the data sent by client
                  String res = dis.readUTF();
                  System.out.println("Message Recevied...Successfully!!!");
                  System.out.println("The Stuffed Message is : " + res);
        
                  for (int i = 1; i < res.length() - 1; i++) {
        
                     // If data contains a 'D' or 'F' do not unstuff it
                      if (res.charAt(i) == 'D' || res.charAt(i) == 'F')
                          out = out + res.charAt(i);
        
                      // If data contains 'E' followed by 'E', de-stuff the former 'E'
                      else if (res.charAt(i) == 'E' && res.charAt(i + 1) == 'E') {
                          out = out + 'E';
                          i++;
                      }
                  }
                  System.out.println("The Destuffed Message is : " + out);
                  dos.writeUTF("success");
                  String ch = dis.readUTF();
                  if (ch.equals("bye")) {
                      System.out.println("Messaging is over.....EXITING");
                      break;
                  }
              }
        
              // Closing all connections
              socket.close();
              dis.close();
              dos.close();
          }
      }

      chevron_right

      
      

      The Server (Receiver) should start running prior to the Client (Sender). This is essential because the client needs an open connection (socket) to send the data and this connection is opened by the server.

      Output

      At Client (Sender) Side
      Enter the Message to be Sent : 
      DFEDDFED
      The data being sent (with byte stuffed) is : FDEFEEDDEFEEDF
      Seding Message....
      Thanks for the Feedback Server!!
      
      At Server (Receiver) Side
      Message Recevied...Successfully!!!
      The Stuffed Message is : FDEFEEDDEFEEDF
      The Destuffed Message is : DFEDDFED
      Messaging is over.....EXITING
      


      My Personal Notes arrow_drop_up

      Check out this Author's contributed articles.

      If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

      Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.