Java 使用比特塞满错误检测技术
数据被封装在数据链路层的帧中并通过网络发送。比特填充是一种错误检测技术。
使用的理念非常简单。每个帧以一个特殊的位模式 “01111110 “开始和结束,这是一个标志字节。每当发送方的数据链路层在数据中遇到五个连续的1时,它就会自动在流出的比特流中塞入一个0比特。该位塞入类似于字节塞入,即在数据中的标志字节之前,将一个转义字节塞入正在进行的字符流中。
当接收器看到五个连续的1比特,然后是一个0比特,它会自动染指(删除)0比特。位填充对发送方和接收方计算机的网络层来说是完全透明的。
有了位填充,两个帧之间的边界可以通过标志模式毫不含糊地识别。因此,如果接收方失去了它所处的位置,它所要做的就是扫描输入的标志序列,因为它们只能出现在帧的边界,而不是在数据中。
举例说明:
发送方(客户端):
用户输入一个二进制数据作为输入。
输入数据。
0000001
数据被塞入并被发送到接收方进行解塞。
这里服务器是接收方。
填充在客户端的数据:011111100000001111110
发送到服务器进行解压缩
接收方(服务器):
接收方收到塞满的数据。
来自客户端的填充数据:011111100000001011110
接收方必须从发送方解开输入的数据,得到用户输入的原始数据。
用户输入的原始数据。
解压缩的数据。
0000001
以下是上述逻辑的代码实现。
在发送方(客户端)
package bitstuffing;
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class BitStuffingClient {
public static void main(String[] args) throws IOException
{
// Opens a socket for connection
Socket socket = new Socket("localhost", 6789);
DataInputStream dis = new DataInputStream(socket.getInputStream());
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
// Scanner class object to take input
Scanner sc = new Scanner(System.in);
// Takes input of unstuffed data from user
System.out.println("Enter data: ");
String data = sc.nextLine();
int cnt = 0;
String s = "";
for (int i = 0; i < data.length(); i++) {
char ch = data.charAt(i);
if (ch == '1') {
// count number of consecutive 1's
// in user's data
cnt++;
if (cnt < 5)
s += ch;
else {
// add one '0' after 5 consecutive 1's
s = s + ch + '0';
cnt = 0;
}
}
else {
s += ch;
cnt = 0;
}
}
// add flag byte in the beginning
// and end of stuffed data
s = "01111110" + s + "01111110";
System.out.println("Data stuffed in client: " + s);
System.out.println("Sending to server for unstuffing");
dos.writeUTF(s);
}
}
在接收方(服务器方)
package bitstuffing;
import java.io.*;
import java.net.*;
public class BitStuffingServer {
public static void main(String[] args) throws IOException
{
ServerSocket skt = new ServerSocket(6789);
// Used to block until a client connects to the server
Socket socket = skt.accept();
DataInputStream dis = new DataInputStream(socket.getInputStream());
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
// Receiving the string from the client which
// needs to be stuffed
String s = dis.readUTF();
System.out.println("Stuffed data from client: " + s);
System.out.println("Unstuffed data: ");
int cnt = 0;
// removal of stuffed bits:
// start from 9th bit because the first 8
// bits are of the special pattern.
for (int i = 8; i < s.length() - 8; i++) {
char ch = s.charAt(i);
if (ch == '1') {
cnt++;
System.out.print(ch);
// After 5 consecutive 1's one stuffed bit
//'0' is added. We need to remove that.
if (cnt == 5) {
i++;
cnt = 0;
}
}
else {
// print unstuffed data
System.out.print(ch);
// we only need to maintain count
// of consecutive 1's
cnt = 0;
}
}
System.out.println();
}
}
输入和输出如上图所示。