串行连接复位错误的位

时间:2017-06-21 20:29:34

标签: java serial-port serial-communication

我创建了一个服务器/客户端JAVA应用程序,它使用串行通信(RXTXComm Library)发送和接收文件。
由于我的项目,链接可以在传输过程中被物理切断,所以我实现了一个滑动窗口和一个连接重置代码,据说在重新建立网络后恢复传输。

问题是,连接被切断并重新建立后收到的数据已损坏

服务器代码"接收器":

bytesRead = in.read(mybytearray, 0, mybytearray.length);
System.out.println("R\t Bytes read\t" + bytesRead);
current = bytesRead;
System.out.println("R\t\t FIRST Last byte recieved \t" + current);
outR.writeLong((current + 1));
outR.flush();
System.out.println("R\t\tSending ACK");

while (true) {
    do {
        bytesRead = in.read(mybytearray, current, (mybytearray.length - current));
        System.out.println("R\t Bytes read\t" + bytesRead);
        if (bytesRead >= 0) current += bytesRead;
        System.out.println("R\t\tLast byte recieved \t" + current);
        //ACK = Integer.toString((current+1));
        outR.writeLong((current + 1));

        outR.flush();
        System.out.println("R\t\tSending ACK");

    } while (bytesRead > 0);
    //in.close();

    if ((mybytearray[current - 1] & 0xff) != 0b01000101) {
        int timer = 0;
        boolean loop = true;
        while (loop) {
            timer++;
            Thread.sleep(1000);
            if (timer > 5) {

                System.out.println("R\t\t Connection Timeout");
                timer = 0;
                current = 0;
                break;
            }
        }
    } else {
        break;
    }
}
bos.write(mybytearray, 0, current - 1);
bos.flush();
System.out.println("R\t\tfinished recieving");
bos.close();

这是客户"发件人"

public static class InReciever implements Runnable {
    DataInputStream inS;
    public InReciever(DataInputStream in) {
        inS = in;
    }

    @Override
    public void run() {
        try {
            //int timer=0;
            while (true) {
                long ack = 0;

                if (brek)
                    break;
                if ((ack = inS.readLong()) > 0) {

                    firstACK = false;
                    windowStart = ack;

                    System.out.println("S\t\tRecieving ack");
                    System.out.println("S\tNext byte to send\t" + ack);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public static class SerialWriter implements Runnable {
    OutputStream out;
    DataInputStream inS;
    DataOutputStream outHello;
    byte[] mybytearray;

    public SerialWriter(OutputStream out, DataInputStream in, DataOutputStream outHello, byte[] buffer) {
        this.out = out;
        inS = in;
        this.outHello = outHello;
        mybytearray = buffer;
    }

    public void run() {
        try {
            new Thread(new InReciever(inS)).start();
            for (int i = 0; i < mybytearray.length; i++) {
                //System.out.println("windowEnd \t"+windowEnd);
                out.write(mybytearray[i]);
                out.flush();
                int timer = 0;
                while (windowEnd > (windowStart + 2000) && !firstACK) {
                    timer++;
                    Thread.sleep(1000);

                    if (timer > 5) {
                        System.out.println("S\tTimeout \n Restart connection \t");
                        i = -1;
                        out.flush();
                        windowStart = 0;
                        windowEnd = 0;
                        firstACK = true;
                    }
                    //Thread.sleep(100);
                    //
                }
                windowEnd++;
            }
            outHello.writeChar('E');
            outHello.flush();
            System.out.println("s\tfinished sending");
            brek = true;

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我没有分析每行代码,但我没有看到任何形式的验证。串行通信通常采用多种形式的验证,例如数据包检查。

您是否尝试将流分成较小的块并一次发送一个块?发送方应该包括某种类型的CRC校验和计算,以及接收方可以验证的每个块。

重新启动中断后,接收方将使用CRC校验和验证最新的块。如果它不匹配,则丢弃该块并从其停止的地方重新启动。

我怀疑你的“重启”代码没有正确地丢弃损坏的数据。