我有一个数据通道,可以通过它传输一些数据,该通道是我自己实现的无线系统,可靠性低90%
,非常low bandwidth
受物理限制。
为了克服这个问题,我计划用一个应该使用一些数据正确方法的系统来包装整个数据通道,并在数据损坏时发送重新发送请求(将使用校验和检查损坏)。
每当其中一个包装器接收到错误数据时,它就会发送一个resend request
,并在堆栈中为未知数据保留内存中的位置。当可靠性下降时,堆栈将快速增长,因为每一方都将开始resend request
相互发送,因为它最后没有收到resend request
。即使可靠性恢复正常,它也会尝试重新发送所有的,resend requests
直到堆栈变空。
这将影响带宽,因为大多数请求不会是数据,而是resend requests
。此外,该系统将在 RAM 非常有限的微控制器上运行,只有几个字节,这在极少数情况下可能会导致堆栈溢出。
有什么建议么?
这是一个描述数据通道的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);
}
}
这是一个UnReliable 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);
}
}
这是我之前描述的可靠通道实现
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;
}
}