gpt4 book ai didi

java - 通过不可靠 channel 进行可靠数据传输

转载 作者:行者123 更新时间:2023-12-02 07:42:14 25 4
gpt4 key购买 nike

我有一个数据通道,可以通过它传输一些数据,该 channel 是我自己实现的无线系统,可靠性较低90%并且由于低带宽 body 限制。

为了克服这个问题,我计划用一个系统包装整个数据通道,该系统应该使用一些数据正确方法,并在数据损坏时发送重新发送请求(将使用校验和检查损坏情况) .

每当包装器之一收到错误数据时,它就会发送重新发送请求,并在内存中为未知数据保留堆栈中的位置。当可靠性下降时,堆栈将快速增长,因为双方都将开始向对方发送重发请求,因为它还没有收到最后一个重发请求。即使可靠性恢复正常,它也会尝试重新发送所有重发请求,直到堆栈变空。

这将影响带宽,因为大多数请求不是数据,而是重新发送请求。此外,该系统将在 RAM 非常有限的微 Controller 上运行,只有几个字节,这在极少数情况下可能会导致堆栈溢出。

有什么建议吗?

这是一个描述数据通道的 Java 模型:

public interface DataChannel {

abstract void send(String s);
abstract void setOnDataListener(OnDataListener l);

interface OnDataListener {
abstract void onData(String s);
}

}

这是 DataChannel 的抽象类,它简化了稍后的实现

public abstract class AbstractReliableChannel implements DataChannel,OnDataListener {

protected DataChannel mUnReliable;
private OnDataListener mUnDataListener;

public AbstractReliableChannel(DataChannel unReliableChannel){
mUnReliable = unReliableChannel;
}

@Override
public abstract void send(String s);

@Override
final public void setOnDataListener(OnDataListener l) {
mUnDataListener = l;
}

/*
* Should be called by the implimanting class
*/
final protected void notifiyListenerThatDataReceived(String s){
mUnDataListener.onData(s);
}

/**
* should be called by the implanting class
*/
final protected void sendOverUnreliableChannel(String s){
mUnReliable.send(s);
}

}

这是一个不可靠 channel 的实现

public class UnReliableChannel extends AbstractReliableChannel {

public ReliableChannel(DataChannel unReliableChannel) {
super(unReliableChannel);
}

@Override
public void send(String s) {
if( new Random().nextInt(10) % 5 == 0 )
s = ModifyStringRandomly(s);

sendOverUnreliableChannel(s);
}

@Override
public void onData(String s) {
if( new Random().nextInt(10) % 5 == 0 )
s = ModifyStringRandomly(s);

notifiyListenerThatDataReceived(s);
}

}

这是我之前描述的一个可靠的 channel 实现

public class ReliableChannel extends AbstractReliableChannel implements Runnable {

public static String DATA = "D";
public static String RESEND = "R";
public static String OK = "O";
private Thread mThread;

public ReliableChannel(DataChannel unReliableChannel) {
super(unReliableChannel);
mThread = new Thread(this);
mThread.start();
}

private Stack<String> mSend;

@Override
public void send(String s) {
mSend.add(s);
}

@Override
public void onData(String s) {
if(isDataValid(s)){
if(s.equals(RESEND)){
String toResend = mSend.pop();
mSend.push(toResend);
mThread.notify();
} else if (s.equals(OK) ) {
mSend.pop();
mThread.notify();
} else if(s.startsWith(DATA)){
notifiyListenerThatDataReceived(s.substring(1));
mSend.push(OK);
}
} else {
mSend.add(RESEND);
mThread.notify();
}
}

private void sendOverUnreliableChannelWithCheckSum(String s){
// ADD checkSUM
sendOverUnreliableChannel(RESEND);
}

@Override
public void run() {
while(true){
while(mSend.isEmpty())
;
sendOverUnreliableChannelWithCheckSum(mSend.pop());
mThread.wait();
}
}


private boolean isDataValid(String s){
// SHOULD BE SOME CHECKSUM IMPLEMINTATION
return true;
}


}

最佳答案

问题来自于你低效的协议(protocol)设计,而不是编程。要在有损信道中获得可靠的链路,只需使用 tcp 连接或定义类似于 tcp 的协议(protocol)即可。基本上,在 Tx 处对每个数据包进行编号。在 Rx 中,当您收到坏数据包时,只需将其丢弃以节省内存。您可以通过检查所有数据包是否具有连续编号来检查数据包的完整性。通过保持适当的滑动窗口,您将获得良好的有效带宽和负担得起的内存使用量。

关于java - 通过不可靠 channel 进行可靠数据传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18406375/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com