一部のデータを転送できるデータチャネルがあります。このチャネルは、信頼性が低く、物理的な制限が原因で、自分で実装したワイヤレスシステム90%
ですlow bandwidth
。
これを克服するために、データ チャネル全体を、データの正しい方法を使用するシステムでラップし、データが破損したときに再送信の要求を送信することを計画しています (破損はチェックサムでチェックされます)。
ラッパーの 1 つが不良データを受信するたびに を送信し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;
}
}