3

一部のデータを転送できるデータチャネルがあります。このチャネルは、信頼性が低く、物理的な制限が原因で、自分で実装したワイヤレスシステム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;
    }


}
4

1 に答える 1