java - Reliable data transfer over an UnReliable Channel -
i have data channel can transfer data on it, channel wireless system implemented myself low reliability 90%
, low bandwidth
due physical limitation.
in order overcome this, i'm planning wrap whole data channel system should use data correct method, , send request resend when when data corrupted (corruption checked checksum).
whenever 1 of wrapper receives bad data send resend request
, , hold place in memory unknown data, in stack.the stack grow when reliability drops down, since each side start send resend request
each other since had not received last resend request
. when reliability returns normal, try resend resend requests
until stack goes empty.
this affect bandwidth since of request won't data, resend requests
.moreover system run on microcontroller limited ram, few bytes, may cause stack overflow in rare cases.
any suggestions?
here java
model describes data channel:
public interface datachannel { abstract void send(string s); abstract void setondatalistener(ondatalistener l); interface ondatalistener { abstract void ondata(string s); } }
here abstract class datachannel simplifies implementation later on
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 called implimanting class */ final protected void notifiylistenerthatdatareceived(string s){ mundatalistener.ondata(s); } /** * should called implanting class */ final protected void sendoverunreliablechannel(string s){ munreliable.send(s); } }
here implementation of 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); } }
here reliable channel implementation described erlier
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 checksum implemintation return true; } }
the problem comes inefficient protocol design, rather programming. reliable link in lossy channel, use tcp connection or define protocol similar tcp. basically, number each of data packet @ tx. @ rx, when receive bad packet, throw away save memory. check integrity of packets checking whether packets have continuous numbers. maintaining proper sliding window, reach both effective bandwidth , affordable memory usage.
Comments
Post a Comment