网工干货知识

超全学习笔记
当前位置:首页 > 干货知识

使用Java实现字节填充功能

更新时间:2026年03月27日   作者:spoto   标签(Tag):
需要填充字节的需求在数据链路层的可变大小帧结构中,我们需要一种方法来区分不同的帧。为了实现这一功能,采用了字节填充技术。字节填充在帧的开头与结尾处,会添加一个8位标志(“F”)。这个标志的作用就是用来区分不同的帧。 因此,每当遇到一个“F”标志时,它都表示某个帧的开始或结束。 不过,这个巧妙的方案会引出一个问题:如果“F”这个标志出现在帧本身所携带的数据中,那么就会产生矛盾。 在这种情况下,字节填充机制就派上了用场了。当在帧中出现的标志模式之前,还会额外插入一个8位的转义序列(“E”),以此来填充原始数据。 此时,接收方需要去除那些用于分隔数据的额外字符,以便得到原始数据。在此时,可能会有一个简单的问题:如果用于分隔数据的字符本身也是数据的一部分,那该怎么办呢?这种情况的处理方式与上述情况相同,即在原始数据中再添加8位长的分隔字符。在以字符为单位的协议中,由于要传输的数据是由8位字符组成的,因此通常会使用字节填充的方法来处理上述问题。为了简化问题,我们只需考虑三种类型的字节序列即可。F旗帜序列E逃生序列D任何其他数据序列
在发送端
Enter the Message to be Sent : 
DDEDFFDE
The data being sent (with byte stuffed) is : FDDEEDEFEFDEEF
Seding Message....
Thanks for the Feedback Server!!

在接收端
Message Received...Successfully!!!
The Stuffed Message is : FDDEEDEFEFDEEF
The Destuffed Message is : DDEDFFDE
Messaging is over.....EXITING
从上面的例子中,我们可以看到原始数据是如何在接收端被恢复出来的。接近方式/方法在发送方(客户端)端
  1. 在发送端,每帧数据的开头和结尾都包含了一个8位长的标志序列(“F”)。
  2. 接下来,会扫描这些数据,以查看是否有一些类似的标志序列(“F”)存在于其中。如果存在这样的标志序列,那么在每个这样的标志序列之前,都会插入一个额外的转义序列(“E”)。
  3. 现在,如果发现有类似的转义序列(“E”),并且该转义序列是所要发送的数据的一部分,那么会在每个这样的转义序列出现之前,再插入一个额外的转义序列(“E”)。
  4. 最后,这些经过处理的数据会被发送者发送出去。
  5. 在接收端(服务器侧)
    1. 接收器会跳过数据中的第一个和最后一个字节。因为这些字节只是用来标记一个帧的开始和结束而已,它们并不包含任何有用的数据。
    2. 从下一个字节开始,数据会被逐位读取。如果连续出现两个转义序列(“E”),那么第一个转义序列会被忽略。同样地,如果某个转义序列之后跟着一个标志序列(“F”),那么该转义序列也会被忽略。
    3. 这种策略有助于接收方准确恢复发送过来的实际数据。
    4. 实施/执行在发送方(客户端)端Java
      // 用于Byte_Stuffing发送方的Java代码包/文件夹字节填充;进口java.io.*;进口java.util.*;进口java.net.*;公共的类/类别 Byte_Stuffing_Client{公开的静态的无效/无意义主要/核心(字符串参数/变量[])投掷/扔掉IOException{InetAddressip=InetAddress.获取本地主机信息();整数港口=45678;扫描仪sc=新的扫描仪(系统/体系.in);// 打开一个用于连接的套接字套接字s=新的套接字(ip,港口);// 声明输入/输出流DataInputStream=新的DataInputStream(s.获取输入流());DataOutputStreamdos=新的DataOutputStream(s.获取输出流());当…的时候(真的/正确的){系统/体系.出去.println(请输入要发送的消息:);字符串数据=sc.下一个行();字符串结果/后果=新的字符串();// 每帧中的数据在开头和结尾处都都会被加上“F”作为标记。数据=‘F’+数据+‘F’;为了(整数i=0;i<数据.长度();i++){// 如果在要发送的数据中发现了‘F’,则将其替换为‘E’。if(数据.charAt(i)==‘F’&&i!=0&&i!=(数据.长度()-1))结果/后果=结果/后果+‘E’+数据.charAt(i);// 如果发送的数据中包含字母‘E’,则将其添加到数据中。否则if(数据.charAt(i)==‘E’)结果/后果=结果/后果+‘E’+数据.charAt(i);否则结果/后果=结果/后果+数据.charAt(i);}系统/体系.外出/离开.println(所发送的数据(包含字节数据)如下:+结果/后果);// 将数据发送给接收方dos.写入UTF格式的数据(结果/后果);系统/体系.出去.println(“删除消息……”);if(.读取UTF编码的文本().等于(“成功”))系统/体系.外出/离开.println(感谢您的反馈!服务器很棒!!);// 消息发送结束dos.写入UTF格式的数据(再见);打破/终止;}// 关闭所有连接s.关闭();dis.关闭();dos.关闭();}}
      在接收端(服务器侧)Java
      // 用于Byte_Stuffing接收器的Java代码包/套餐字节填充;进口java.io.*;进口java.net.*;公共的类/类别 Byte_Stuffing{公共的静态的无效/无意义主要/核心(字符串[]参数/变量)投掷/抛洒IOException{// 打开一个用于连接的套接字ServerSocketservsock=新的ServerSocket(45678);// 用于阻塞,直到有客户端连接到服务器为止。套接字插座=servsock.接受();// 声明输入/输出流DataInputStreamdis=新的DataInputStream(插座.获取输入流());DataOutputStreamdos=新的DataOutputStream(插座.获取输出流());(真的/正确的){字符串外出/离开=新的字符串();// 用于读取客户端发送的数据。字符串结果/后果=dis.读取UTF编码的文本();系统/体系.外出/离开.println(“消息已接收……成功!!!”);系统/体系.出去/离开.println(“填充后的消息是:”+结果/后果);为了(整数i=1;i<结果/后果.长度()-1;i++){// 如果数据中包含‘D’或‘F’,则不要将其解包。if(结果/后果.charAt(i)==‘D’||结果/后果.charAt(i)==‘F’)出去/离开=外出/离开+结果/后果.charAt(i);// 如果数据中包含连续的“E”,那么需要删除前面的“E”。否则if(结果/后果.charAt(i)==‘E’&&结果/后果.charAt(i+1)==‘E’){外出/离开=外出/离开+‘E’;i++;}}系统/体系.外出/离开.println(“这条消息的内容是:”+外出/离开);dos.写入UTF格式的数据(“成功”);字符串ch=dis.读取UTF编码的文本();if(ch.等于(再见)){系统/体系.外出/离开.println(消息传递功能已经停止了……现在可以退出了。);打破/终止;}}// 关闭所有连接插座.关闭();.关闭();dos.关闭();}}
      服务器(或接收方)应该在客户端(或发送方)之前开始运行。这一点非常重要,因为客户端需要有一个可用的连接来发送数据,而这个连接是由服务器来建立的。输出结果/内容
      在客户端(发送方)端
      Enter the Message to be Sent : 
      DFEDDFED
      The data being sent (with byte stuffed) is : FDEFEEDDEFEEDF
      Seding Message....
      Thanks for the Feedback Server!!
      
      在服务器(接收端)方面
      Message Received...Successfully!!!
      The Stuffed Message is : FDEFEEDDEFEEDF
      The Destuffed Message is : DFEDDFED
      Messaging is over.....EXITING
      
              马上抢免费试听资格
意向课程:*必选
姓名:*必填
联系方式:*必填
QQ:
思博SPOTO在线咨询

上一篇: 无线连接的方式

下一篇: 消息交换技术

相关资讯

即刻预约

免费试听-咨询课程-获取免费资料