我创建了一个服务器/客户端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();
}
}
}
答案 0 :(得分:0)
我没有分析每行代码,但我没有看到任何形式的验证。串行通信通常采用多种形式的验证,例如数据包检查。
您是否尝试将流分成较小的块并一次发送一个块?发送方应该包括某种类型的CRC校验和计算,以及接收方可以验证的每个块。
重新启动中断后,接收方将使用CRC校验和验证最新的块。如果它不匹配,则丢弃该块并从其停止的地方重新启动。
我怀疑你的“重启”代码没有正确地丢弃损坏的数据。