Thread: [Udt-java-commits] SF.net SVN: udt-java:[18] udt-java/trunk/src
Status: Alpha
Brought to you by:
bschuller
From: <bsc...@us...> - 2010-04-16 21:05:20
|
Revision: 18 http://udt-java.svn.sourceforge.net/udt-java/?rev=18&view=rev Author: bschuller Date: 2010-04-16 21:05:13 +0000 (Fri, 16 Apr 2010) Log Message: ----------- cc made configurable; tried to optimize loss lists Modified Paths: -------------- udt-java/trunk/src/main/java/udt/UDPEndPoint.java udt-java/trunk/src/main/java/udt/UDTCongestionControl.java udt-java/trunk/src/main/java/udt/UDTInputStream.java udt-java/trunk/src/main/java/udt/UDTReceiver.java udt-java/trunk/src/main/java/udt/UDTSender.java udt-java/trunk/src/main/java/udt/UDTSession.java udt-java/trunk/src/main/java/udt/UDTSocket.java udt-java/trunk/src/main/java/udt/packets/NegativeAcknowledgement.java udt-java/trunk/src/main/java/udt/receiver/ReceiverLossList.java udt-java/trunk/src/main/java/udt/receiver/ReceiverLossListEntry.java udt-java/trunk/src/main/java/udt/sender/SenderLossList.java udt-java/trunk/src/main/java/udt/sender/SenderLossListEntry.java udt-java/trunk/src/main/java/udt/util/CircularArray.java udt-java/trunk/src/main/java/udt/util/FlowWindow.java udt-java/trunk/src/main/java/udt/util/UDTStatistics.java udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java udt-java/trunk/src/test/java/udt/performance/UDPTest.java Added Paths: ----------- udt-java/trunk/src/main/java/udt/CongestionControl.java udt-java/trunk/src/test/java/udt/NullCongestionControl.java Added: udt-java/trunk/src/main/java/udt/CongestionControl.java =================================================================== --- udt-java/trunk/src/main/java/udt/CongestionControl.java (rev 0) +++ udt-java/trunk/src/main/java/udt/CongestionControl.java 2010-04-16 21:05:13 UTC (rev 18) @@ -0,0 +1,74 @@ +package udt; + +import java.util.List; + +/** + * congestion control interface + */ +public interface CongestionControl { + + /** + * Callback function to be called (only) at the start of a UDT connection. + * when the UDT socket is conected + */ + public abstract void init(); + + /** + * set roundtrip time and associated variance + */ + public abstract void setRTT(long rtt, long rttVar); + + /** + * set packet arrival rate and link capacity + * @param rate + * @param linkCapacity + */ + public abstract void setPacketArrivalRate(long rate, long linkCapacity); + + /** + * Inter-packet interval in seconds + * @return + */ + public abstract double getSendInterval(); + + /** + * get the congestion window size + */ + public abstract long getCongestionWindowSize(); + + /** + * Callback function to be called when an ACK packet is received. + * @param ackSeqno: the data sequence number acknowledged by this ACK. + * see spec. page(16-17) + */ + public abstract void onACK(long ackSeqno); + + /** + * Callback function to be called when a loss report is received. + * @param lossInfo:list of sequence number of packets, in the format describled in packet.cpp. + */ + public abstract void onNAK(List<Integer> lossInfo); + + /** + * Callback function to be called when a timeout event occurs + */ + public abstract void onTimeout(); + + /** + * Callback function to be called when a data is sent. + * @param packetSeqNo: the data sequence number. + */ + public abstract void onPacketSend(long packetSeqNo); + + /** + * Callback function to be called when a data is received. + * @param packetSeqNo: the data sequence number. + */ + public abstract void onPacketReceive(long packetSeqNo); + + /** + * Callback function to be called when a UDT connection is closed. + */ + public abstract void close(); + +} \ No newline at end of file Property changes on: udt-java/trunk/src/main/java/udt/CongestionControl.java ___________________________________________________________________ Added: svn:mime-type + text/plain Modified: udt-java/trunk/src/main/java/udt/UDPEndPoint.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDPEndPoint.java 2010-04-16 13:15:20 UTC (rev 17) +++ udt-java/trunk/src/main/java/udt/UDPEndPoint.java 2010-04-16 21:05:13 UTC (rev 18) @@ -55,8 +55,6 @@ /** * the UDPEndpoint takes care of sending and receiving UDP network packets, * dispatching them to the correct {@link UDTSession} - * - * */ public class UDPEndPoint { @@ -83,7 +81,7 @@ //has the endpoint been stopped? private volatile boolean stopped=false; - public static final int DATAGRAM_SIZE=32768; + public static final int DATAGRAM_SIZE=1500; /** * bind to any local port on the given host address Modified: udt-java/trunk/src/main/java/udt/UDTCongestionControl.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTCongestionControl.java 2010-04-16 13:15:20 UTC (rev 17) +++ udt-java/trunk/src/main/java/udt/UDTCongestionControl.java 2010-04-16 21:05:13 UTC (rev 18) @@ -2,12 +2,10 @@ import java.util.List; -import javax.swing.text.Utilities; - import udt.util.UDTStatistics; import udt.util.Util; -public class UDTCongestionControl { +public class UDTCongestionControl implements CongestionControl { private final UDTSession session; private final UDTStatistics statistics; @@ -64,26 +62,30 @@ init(); } - /** - * Callback function to be called (only) at the start of a UDT connection. - * when the UDT socket is conected + /* (non-Javadoc) + * @see udt.CongestionControl#init() */ public void init() { } + /* (non-Javadoc) + * @see udt.CongestionControl#setRTT(long, long) + */ public void setRTT(long rtt, long rttVar){ this.roundTripTime=rtt; } + /* (non-Javadoc) + * @see udt.CongestionControl#setPacketArrivalRate(long, long) + */ public void setPacketArrivalRate(long rate, long linkCapacity){ this.packetArrivalRate=rate; this.estimatedLinkCapacity=linkCapacity; } - /** - * Inter-packet interval in seconds - * @return + /* (non-Javadoc) + * @see udt.CongestionControl#getSendInterval() */ public double getSendInterval(){ return packetSendingPeriod ; @@ -93,14 +95,12 @@ * congestionWindowSize * @return */ - protected long getCongestionWindowSize(){ - return congestionWindowSize; + public long getCongestionWindowSize(){ + return 2048;//congestionWindowSize; } - /** - * Callback function to be called when an ACK packet is received. - * @param ackSeqno: the data sequence number acknowledged by this ACK. - * see spec. page(16-17) + /* (non-Javadoc) + * @see udt.CongestionControl#onACK(long) */ public void onACK(long ackSeqno){ //the fixed size of a UDT packet @@ -143,9 +143,8 @@ return inc; } - /** - * Callback function to be called when a loss report is received. - * @param lossInfo:list of sequence number of packets, in the format describled in packet.cpp. + /* (non-Javadoc) + * @see udt.CongestionControl#onNAK(java.util.List) */ public void onNAK(List<Integer>lossInfo){ long firstBiggestlossSeqNo=lossInfo.get(lossInfo.size()-1); @@ -197,24 +196,22 @@ } } - /** - * Callback function to be called when a timeout event occurs + /* (non-Javadoc) + * @see udt.CongestionControl#onTimeout() */ public void onTimeout(){} - /** - * Callback function to be called when a data is sent. - * @param packetSeqNo: the data sequence number. + /* (non-Javadoc) + * @see udt.CongestionControl#onPacketSend(long) */ public void onPacketSend(long packetSeqNo){} - /** - * Callback function to be called when a data is received. - * @param packetSeqNo: the data sequence number. + /* (non-Javadoc) + * @see udt.CongestionControl#onPacketReceive(long) */ public void onPacketReceive(long packetSeqNo){} - /** - * Callback function to be called when a UDT connection is closed. + /* (non-Javadoc) + * @see udt.CongestionControl#close() */ public void close(){} Modified: udt-java/trunk/src/main/java/udt/UDTInputStream.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTInputStream.java 2010-04-16 13:15:20 UTC (rev 17) +++ udt-java/trunk/src/main/java/udt/UDTInputStream.java 2010-04-16 21:05:13 UTC (rev 18) @@ -60,7 +60,7 @@ private final UDTStatistics statistics; //the highest sequence number read by the application - private long highestSequenceNumber=-1; + private volatile long highestSequenceNumber=0; //set to 'false' by the receiver when it gets a shutdown signal from the peer //see the noMoreData() method @@ -88,8 +88,8 @@ } private int getFlowWindowSize(){ - if(socket!=null)return socket.getSession().getFlowWindowSize(); - else return 64; + if(socket!=null)return 2*socket.getSession().getFlowWindowSize(); + else return 128; } /** * create a new {@link UDTInputStream} connected to the given socket @@ -221,6 +221,7 @@ * */ protected boolean haveNewData(long sequenceNumber,byte[]data)throws IOException{ + if(sequenceNumber<=highestSequenceNumber)return true; return appData.offer(new AppData(sequenceNumber,data)); } @@ -270,6 +271,31 @@ public String toString(){ return sequenceNumber+"["+data.length+"]"; } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + (int) (sequenceNumber ^ (sequenceNumber >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AppData other = (AppData) obj; + if (sequenceNumber != other.sequenceNumber) + return false; + return true; + } + + } } Modified: udt-java/trunk/src/main/java/udt/UDTReceiver.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-04-16 13:15:20 UTC (rev 17) +++ udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-04-16 21:05:13 UTC (rev 18) @@ -84,7 +84,7 @@ private long lastDataPacketArrivalTime=0; //largest received data packet sequence number(LRSN) - private volatile long largestReceivedSeqNumber=-1; + private volatile long largestReceivedSeqNumber=0; //ACK event related @@ -233,7 +233,6 @@ } processUDTPacket(packet); } - //else System.out.println("no packet."); Thread.yield(); } @@ -337,7 +336,6 @@ protected void onDataPacketReceived(DataPacket dp)throws IOException{ long currentSequenceNumber = dp.getPacketSequenceNumber(); - //check whether to drop this packet n++; if(dropRate>0 && n % dropRate == 0){ @@ -412,6 +410,7 @@ protected void sendNAK(List<Long>sequenceNumbers)throws IOException{ if(sequenceNumbers.size()==0)return; NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); + nAckPacket.addLossInfo(sequenceNumbers); nAckPacket.setSession(session); nAckPacket.setDestinationID(session.getDestination().getSocketID()); Modified: udt-java/trunk/src/main/java/udt/UDTSender.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSender.java 2010-04-16 13:15:20 UTC (rev 17) +++ udt-java/trunk/src/main/java/udt/UDTSender.java 2010-04-16 21:05:13 UTC (rev 18) @@ -40,6 +40,7 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; import java.util.logging.Level; import java.util.logging.Logger; @@ -87,7 +88,7 @@ private final AtomicInteger unacknowledged=new AtomicInteger(0); //for generating data packet sequence numbers - private long nextSequenceNumber=-1; + private long nextSequenceNumber=0; //the largest data packet sequence number that has actually been sent out private volatile long largestSentSequenceNumber=-1; @@ -100,6 +101,8 @@ private volatile boolean stopped=false; + private volatile AtomicReference<CountDownLatch> latchRef=new AtomicReference<CountDownLatch>(); + public UDTSender(UDTSession session,UDPEndPoint endpoint){ this.endpoint= endpoint; this.session=session; @@ -110,6 +113,8 @@ sendBuffer=new ConcurrentHashMap<Long, DataPacket>(MAX_SIZE,0.75f,2); sendQueue = new LinkedBlockingQueue<DataPacket>(MAX_SIZE); lastAckSequenceNumber=session.getInitialSequenceNumber(); + + latchRef.set(new CountDownLatch(1)); start(); } @@ -190,8 +195,8 @@ } protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ - if(latch!=null)latch.countDown(); - UDTCongestionControl cc=session.getCongestionControl(); + latchRef.get().countDown(); + CongestionControl cc=session.getCongestionControl(); if(acknowledgement.getPacketReceiveRate()>0){ long rtt=acknowledgement.getRoundTripTime(); long rttVar=acknowledgement.getRoundTripTimeVar(); @@ -230,8 +235,6 @@ for(Integer i: nak.getDecodedLossInfo()){ senderLossList.insert(new SenderLossListEntry(i)); } - //update SND TODO - session.getCongestionControl().onNAK(nak.getDecodedLossInfo()); //reset EXP. EXP is in the receiver currently.... maybe move to SOCKET? session.getSocket().getReceiver().resetEXPTimer(); @@ -297,7 +300,7 @@ statistics.incNumberOfCCSlowDownEvents(); return; } - DataPacket dp=sendQueue.poll(10,TimeUnit.MILLISECONDS); + DataPacket dp=sendQueue.poll(100,TimeUnit.MILLISECONDS); if(dp!=null){ lastSentTime=Util.getCurrentTime(); send(dp); @@ -309,8 +312,9 @@ statistics.incNumberOfCCWindowExceededEvents(); } } + Thread.yield(); } - Thread.yield(); + } /** @@ -363,16 +367,14 @@ return senderLossList.isEmpty(); } - private volatile CountDownLatch latch=null; - /** * wait for the next acknowledge * @throws InterruptedException */ - public void waitForAck(long sequenceNumber)throws InterruptedException{ - latch=new CountDownLatch(1); + public synchronized void waitForAck(long sequenceNumber)throws InterruptedException{ while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ - latch.await(10, TimeUnit.MILLISECONDS); + latchRef.set(new CountDownLatch(1)); + latchRef.get().await(10, TimeUnit.MILLISECONDS); } } Modified: udt-java/trunk/src/main/java/udt/UDTSession.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSession.java 2010-04-16 13:15:20 UTC (rev 17) +++ udt-java/trunk/src/main/java/udt/UDTSession.java 2010-04-16 21:05:13 UTC (rev 18) @@ -62,13 +62,13 @@ protected int receiveBufferSize=64*32768; - protected final UDTCongestionControl cc; + protected final CongestionControl cc; /** * flow window size, i.e. how many data packets are * in-flight at a single time */ - protected int flowWindowSize=32; + protected int flowWindowSize=64; /** * remote UDT entity (address and socket ID) @@ -84,6 +84,12 @@ public static final int DEFAULT_DATAGRAM_SIZE=UDPEndPoint.DATAGRAM_SIZE; /** + * key for a system property defining the CC class to be used + * @see CongestionControl + */ + public static final String CC_CLASS="udt.congestioncontrol.class"; + + /** * Buffer size (i.e. datagram size) * This is negotiated during connection setup */ @@ -99,7 +105,18 @@ statistics=new UDTStatistics(description); mySocketID=nextSocketID.incrementAndGet(); this.destination=destination; - cc=new UDTCongestionControl(this); + + //init configurable CC + String clazzP=System.getProperty(CC_CLASS,UDTCongestionControl.class.getName()); + Object ccObject=null; + try{ + Class<?>clazz=Class.forName(clazzP); + ccObject=clazz.getDeclaredConstructor(UDTSession.class).newInstance(this); + }catch(Exception e){ + ccObject=new UDTCongestionControl(this); + } + cc=(CongestionControl)ccObject; + System.out.println("using "+cc.getClass().getName()); } public abstract void received(UDTPacket packet, Destination peer); @@ -108,7 +125,7 @@ return socket; } - public UDTCongestionControl getCongestionControl() { + public CongestionControl getCongestionControl() { return cc; } Modified: udt-java/trunk/src/main/java/udt/UDTSocket.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSocket.java 2010-04-16 13:15:20 UTC (rev 17) +++ udt-java/trunk/src/main/java/udt/UDTSocket.java 2010-04-16 21:05:13 UTC (rev 18) @@ -182,7 +182,7 @@ packet.setData(chunk); //put the packet into the send queue while(!sender.sendUdtPacket(packet, timeout, units)){ - System.out.println("WAIT"); + System.out.println("SOCKET WAIT"); } } if(length>0)active=true; Modified: udt-java/trunk/src/main/java/udt/packets/NegativeAcknowledgement.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/NegativeAcknowledgement.java 2010-04-16 13:15:20 UTC (rev 17) +++ udt-java/trunk/src/main/java/udt/packets/NegativeAcknowledgement.java 2010-04-16 21:05:13 UTC (rev 18) @@ -109,7 +109,7 @@ */ public void addLossInfo(long firstSequenceNumber, long lastSequenceNumber) { //check if we really need an interval - if(lastSequenceNumber-firstSequenceNumber==1){ + if(lastSequenceNumber-firstSequenceNumber==0){ addLossInfo(firstSequenceNumber); return; } Modified: udt-java/trunk/src/main/java/udt/receiver/ReceiverLossList.java =================================================================== --- udt-java/trunk/src/main/java/udt/receiver/ReceiverLossList.java 2010-04-16 13:15:20 UTC (rev 17) +++ udt-java/trunk/src/main/java/udt/receiver/ReceiverLossList.java 2010-04-16 21:05:13 UTC (rev 18) @@ -32,7 +32,7 @@ package udt.receiver; import java.util.ArrayList; -import java.util.Iterator; +import java.util.Arrays; import java.util.List; import java.util.concurrent.PriorityBlockingQueue; @@ -50,25 +50,18 @@ public ReceiverLossList(){ backingList = new PriorityBlockingQueue<ReceiverLossListEntry>(16); - } + } public void insert(ReceiverLossListEntry entry){ - backingList.add(entry); + synchronized (backingList) { + if(!backingList.contains(entry)){ + backingList.add(entry); + } + } } - - public void remove(ReceiverLossListEntry obj){ - backingList.remove(obj); - } public void remove(long seqNo){ - Iterator<ReceiverLossListEntry>iterator=backingList.iterator(); - while(iterator.hasNext()){ - ReceiverLossListEntry e=iterator.next(); - if(e.getSequenceNumber()==seqNo){ - iterator.remove(); - break; - } - } + backingList.remove(new ReceiverLossListEntry(seqNo)); } public boolean contains(ReceiverLossListEntry obj){ @@ -102,8 +95,10 @@ public List<Long>getFilteredSequenceNumbers(long RTT, boolean doFeedback){ List<Long>result=new ArrayList<Long>(); long now=Util.getCurrentTime(); - for(ReceiverLossListEntry e: backingList){ - if( (now-e.getLastFeedbackTime())>2*RTT){ + ReceiverLossListEntry[]sorted=backingList.toArray(new ReceiverLossListEntry[0]); + Arrays.sort(sorted); + for(ReceiverLossListEntry e: sorted){ + if( (now-e.getLastFeedbackTime())>e.getK()*RTT){ result.add(e.getSequenceNumber()); if(doFeedback)e.feedback(); } Modified: udt-java/trunk/src/main/java/udt/receiver/ReceiverLossListEntry.java =================================================================== --- udt-java/trunk/src/main/java/udt/receiver/ReceiverLossListEntry.java 2010-04-16 13:15:20 UTC (rev 17) +++ udt-java/trunk/src/main/java/udt/receiver/ReceiverLossListEntry.java 2010-04-16 21:05:13 UTC (rev 18) @@ -48,7 +48,9 @@ * @param sequenceNumber */ public ReceiverLossListEntry(long sequenceNumber){ - if(sequenceNumber<=0)throw new IllegalArgumentException(); + if(sequenceNumber<=0){ + throw new IllegalArgumentException("Got sequence number "+sequenceNumber); + } this.sequenceNumber = sequenceNumber; this.lastFeedbacktime=Util.getCurrentTime(); } @@ -90,4 +92,30 @@ return sequenceNumber+"[k="+k+",time="+lastFeedbacktime+"]"; } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (int) (k ^ (k >>> 32)); + result = prime * result + + (int) (sequenceNumber ^ (sequenceNumber >>> 32)); + return result; + } + + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ReceiverLossListEntry other = (ReceiverLossListEntry) obj; + if (sequenceNumber != other.sequenceNumber) + return false; + return true; + } + } Modified: udt-java/trunk/src/main/java/udt/sender/SenderLossList.java =================================================================== --- udt-java/trunk/src/main/java/udt/sender/SenderLossList.java 2010-04-16 13:15:20 UTC (rev 17) +++ udt-java/trunk/src/main/java/udt/sender/SenderLossList.java 2010-04-16 21:05:13 UTC (rev 18) @@ -49,7 +49,9 @@ } public void insert(SenderLossListEntry obj){ - backingList.add(obj); + synchronized (backingList) { + if(!backingList.contains(obj))backingList.add(obj); + } } public void remove(long seqNo){ @@ -61,6 +63,7 @@ return; } } + //backingList.remove(new SenderLossListEntry(seqNo)); } /** Modified: udt-java/trunk/src/main/java/udt/sender/SenderLossListEntry.java =================================================================== --- udt-java/trunk/src/main/java/udt/sender/SenderLossListEntry.java 2010-04-16 13:15:20 UTC (rev 17) +++ udt-java/trunk/src/main/java/udt/sender/SenderLossListEntry.java 2010-04-16 21:05:13 UTC (rev 18) @@ -71,4 +71,27 @@ return (int)(sequenceNumber-o.sequenceNumber); } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + (int) (sequenceNumber ^ (sequenceNumber >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + SenderLossListEntry other = (SenderLossListEntry) obj; + if (sequenceNumber != other.sequenceNumber) + return false; + return true; + } + } Modified: udt-java/trunk/src/main/java/udt/util/CircularArray.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/CircularArray.java 2010-04-16 13:15:20 UTC (rev 17) +++ udt-java/trunk/src/main/java/udt/util/CircularArray.java 2010-04-16 21:05:13 UTC (rev 18) @@ -35,18 +35,23 @@ import java.util.ArrayList; import java.util.List; +/** + * Circular array: the most recent value overwrites the oldest one if there is no more free + * space in the array + */ public class CircularArray<T>{ protected int position=0; + protected boolean haveOverflow=false; - //the maximum number of entries - protected int max=1; - protected List<T>circularArray; + protected final int max; + protected final List<T>circularArray; + /** - * ArrayList von T(object's type). The most recent value overwrite the oldest one - * if no more free space in the array + * Create a new circularArray of the given size + * * @param size */ public CircularArray(int size){ @@ -55,10 +60,7 @@ } /** - * Insert the specified entry at the specified position in this list. - * the most recent value overwrite the oldest one - * if no more free space in the circularArray - * @param entry + * add an entry */ public void add(T entry){ if(position>=max){ @@ -74,7 +76,6 @@ /** * Returns the number of elements in this list - * @return */ public int size(){ return circularArray.size(); @@ -83,7 +84,5 @@ public String toString(){ return circularArray.toString(); } - - - + } Modified: udt-java/trunk/src/main/java/udt/util/FlowWindow.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/FlowWindow.java 2010-04-16 13:15:20 UTC (rev 17) +++ udt-java/trunk/src/main/java/udt/util/FlowWindow.java 2010-04-16 21:05:13 UTC (rev 18) @@ -74,6 +74,9 @@ */ @Override public boolean offer(E e) { + if(contains(e)){ + return true; + } if(size()<capacity){ return super.offer(e); }else return false; Modified: udt-java/trunk/src/main/java/udt/util/UDTStatistics.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/UDTStatistics.java 2010-04-16 13:15:20 UTC (rev 17) +++ udt-java/trunk/src/main/java/udt/util/UDTStatistics.java 2010-04-16 21:05:13 UTC (rev 18) @@ -33,7 +33,6 @@ package udt.util; import java.io.File; -import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.security.MessageDigest; Added: udt-java/trunk/src/test/java/udt/NullCongestionControl.java =================================================================== --- udt-java/trunk/src/test/java/udt/NullCongestionControl.java (rev 0) +++ udt-java/trunk/src/test/java/udt/NullCongestionControl.java 2010-04-16 21:05:13 UTC (rev 18) @@ -0,0 +1,48 @@ +package udt; + +import java.util.List; + +public class NullCongestionControl implements CongestionControl { + + private final UDTSession session; + + public NullCongestionControl(UDTSession session){ + this.session=session; + } + + public void close() { + } + + public long getCongestionWindowSize() { + return Long.MAX_VALUE; + } + + public double getSendInterval() { + return 0; + } + + public void init() { + } + + public void onACK(long ackSeqno) { + } + + public void onNAK(List<Integer> lossInfo) { + } + + public void onPacketReceive(long packetSeqNo) { + } + + public void onPacketSend(long packetSeqNo) { + } + + public void onTimeout() { + } + + public void setPacketArrivalRate(long rate, long linkCapacity) { + } + + public void setRTT(long rtt, long rttVar) { + } + +} Property changes on: udt-java/trunk/src/test/java/udt/NullCongestionControl.java ___________________________________________________________________ Added: svn:mime-type + text/plain Modified: udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-04-16 13:15:20 UTC (rev 17) +++ udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-04-16 21:05:13 UTC (rev 18) @@ -7,10 +7,12 @@ import java.util.logging.Level; import java.util.logging.Logger; +import udt.NullCongestionControl; import udt.UDTClient; import udt.UDTInputStream; import udt.UDTReceiver; import udt.UDTServerSocket; +import udt.UDTSession; import udt.UDTSocket; import udt.UDTTestBase; import udt.util.UDTStatistics; @@ -20,7 +22,8 @@ boolean running=false; //how many - int num_packets=200; + int num_packets=100; + //how large is a single packet int size=1*1024*1024; @@ -30,6 +33,7 @@ public void test1()throws Exception{ Logger.getLogger("udt").setLevel(Level.INFO); + System.setProperty(UDTSession.CC_CLASS, NullCongestionControl.class.getName()); UDTReceiver.dropRate=0; TIMEOUT=Integer.MAX_VALUE; Modified: udt-java/trunk/src/test/java/udt/performance/UDPTest.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/UDPTest.java 2010-04-16 13:15:20 UTC (rev 17) +++ udt-java/trunk/src/test/java/udt/performance/UDPTest.java 2010-04-16 21:05:13 UTC (rev 18) @@ -3,20 +3,17 @@ import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; -import java.nio.ByteBuffer; import java.util.Random; import junit.framework.TestCase; /** * send some data over a UDP connection and measure performance - * */ public class UDPTest extends TestCase { - final int BUFSIZE=32768; - final int num_packets=10*1000; - final int packetSize=1024; + final int num_packets=100*1000; + final int packetSize=1500; public void test1()throws Exception{ runServer(); @@ -25,20 +22,15 @@ //generate a test array with random content N=num_packets*packetSize; - byte[]data=new byte[N]; + byte[]data=new byte[packetSize]; new Random().nextBytes(data); long start=System.currentTimeMillis(); - ByteBuffer bb=ByteBuffer.wrap(data); - DatagramPacket dp=new DatagramPacket(new byte[BUFSIZE],BUFSIZE); + DatagramPacket dp=new DatagramPacket(new byte[packetSize],packetSize); dp.setAddress(InetAddress.getByName("localhost")); dp.setPort(65321); - - System.out.println("Sending data block of <"+N+"> bytes"); - while(bb.remaining()>0){ - int len=Math.min(bb.remaining(),BUFSIZE); - byte[]chunk=new byte[len]; - bb.get(chunk); - dp.setData(chunk); + System.out.println("Sending "+num_packets+" data blocks of <"+packetSize+"> bytes"); + for(int i=0;i<num_packets;i++){ + dp.setData(data); s.send(dp); } System.out.println("Finished sending."); @@ -46,7 +38,8 @@ System.out.println("Server stopped."); long end=System.currentTimeMillis(); System.out.println("Done. Sending "+N/1024/1024+" Mbytes took "+(end-start)+" ms"); - System.out.println("Rate "+N/(end-start)+" Kbytes/sec"); + System.out.println("Rate "+N/1000/(end-start)+" Mbytes/sec"); + System.out.println("Rate "+num_packets+" packets/sec"); System.out.println("Server received: "+total); } @@ -61,7 +54,7 @@ Runnable serverProcess=new Runnable(){ public void run(){ try{ - byte[]buf=new byte[BUFSIZE]; + byte[]buf=new byte[packetSize]; DatagramPacket dp=new DatagramPacket(buf,buf.length); while(true){ serverSocket.receive(dp); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2010-04-20 20:17:14
|
Revision: 19 http://udt-java.svn.sourceforge.net/udt-java/?rev=19&view=rev Author: bschuller Date: 2010-04-20 20:17:07 +0000 (Tue, 20 Apr 2010) Log Message: ----------- Modified Paths: -------------- udt-java/trunk/src/main/java/udt/CongestionControl.java udt-java/trunk/src/main/java/udt/UDPEndPoint.java udt-java/trunk/src/main/java/udt/UDTCongestionControl.java udt-java/trunk/src/main/java/udt/UDTReceiver.java udt-java/trunk/src/main/java/udt/UDTSender.java udt-java/trunk/src/main/java/udt/UDTSession.java udt-java/trunk/src/main/java/udt/UDTSocket.java udt-java/trunk/src/main/java/udt/packets/DataPacket.java udt-java/trunk/src/main/java/udt/packets/PacketFactory.java udt-java/trunk/src/main/java/udt/packets/PacketUtil.java udt-java/trunk/src/main/java/udt/receiver/PacketPairWindow.java udt-java/trunk/src/main/java/udt/sender/SenderLossList.java udt-java/trunk/src/main/java/udt/util/Util.java udt-java/trunk/src/test/java/udt/NullCongestionControl.java udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java udt-java/trunk/src/test/java/udt/performance/UDPTest.java Modified: udt-java/trunk/src/main/java/udt/CongestionControl.java =================================================================== --- udt-java/trunk/src/main/java/udt/CongestionControl.java 2010-04-16 21:05:13 UTC (rev 18) +++ udt-java/trunk/src/main/java/udt/CongestionControl.java 2010-04-20 20:17:07 UTC (rev 19) @@ -19,12 +19,18 @@ public abstract void setRTT(long rtt, long rttVar); /** - * set packet arrival rate and link capacity + * update packet arrival rate and link capacity with the + * values received in an ACK packet * @param rate * @param linkCapacity */ - public abstract void setPacketArrivalRate(long rate, long linkCapacity); + public abstract void updatePacketArrivalRate(long rate, long linkCapacity); + public long getPacketArrivalRate(); + + public long getEstimatedLinkCapacity(); + + /** * Inter-packet interval in seconds * @return @@ -55,13 +61,13 @@ public abstract void onTimeout(); /** - * Callback function to be called when a data is sent. + * Callback function to be called when a data packet is sent. * @param packetSeqNo: the data sequence number. */ public abstract void onPacketSend(long packetSeqNo); /** - * Callback function to be called when a data is received. + * Callback function to be called when a data packet is received. * @param packetSeqNo: the data sequence number. */ public abstract void onPacketReceive(long packetSeqNo); Modified: udt-java/trunk/src/main/java/udt/UDPEndPoint.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDPEndPoint.java 2010-04-16 21:05:13 UTC (rev 18) +++ udt-java/trunk/src/main/java/udt/UDPEndPoint.java 2010-04-20 20:17:07 UTC (rev 19) @@ -235,6 +235,8 @@ * </ul> * @throws IOException */ + private long lastDestID=-1; + private UDTSession lastSession; protected void doReceive()throws IOException{ try{ try{ @@ -265,7 +267,16 @@ else{ //dispatch to existing session - UDTSession session=sessions.get(packet.getDestinationID()); + long dest=packet.getDestinationID(); + UDTSession session; + if(dest==lastDestID){ + session=lastSession; + } + else{ + session=sessions.get(dest); + lastSession=session; + lastDestID=dest; + } if(session==null){ logger.warning("Unknown session <"+packet.getDestinationID()+"> requested from <"+peer+"> packet type "+packet.getClass().getName()); } Modified: udt-java/trunk/src/main/java/udt/UDTCongestionControl.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTCongestionControl.java 2010-04-16 21:05:13 UTC (rev 18) +++ udt-java/trunk/src/main/java/udt/UDTCongestionControl.java 2010-04-20 20:17:07 UTC (rev 19) @@ -8,15 +8,17 @@ public class UDTCongestionControl implements CongestionControl { private final UDTSession session; + private final UDTStatistics statistics; + //round trip time in microseconds - private long roundTripTime=10*Util.getSYNTime(); + private long roundTripTime=2*Util.getSYNTime(); //rate in packets per second - private long packetArrivalRate=100; + private long packetArrivalRate=0; //link capacity in packets per second - private long estimatedLinkCapacity; + private long estimatedLinkCapacity=0; long maxControlWindowSize=128; @@ -58,15 +60,14 @@ public UDTCongestionControl(UDTSession session){ this.session=session; this.statistics=session.getStatistics(); - lastDecreaseSeqNo= session.getInitialSequenceNumber()-1; + lastDecreaseSeqNo=session.getInitialSequenceNumber()-1; init(); } /* (non-Javadoc) * @see udt.CongestionControl#init() */ - public void init() { - + public void init() { } /* (non-Javadoc) @@ -79,16 +80,27 @@ /* (non-Javadoc) * @see udt.CongestionControl#setPacketArrivalRate(long, long) */ - public void setPacketArrivalRate(long rate, long linkCapacity){ - this.packetArrivalRate=rate; - this.estimatedLinkCapacity=linkCapacity; + public void updatePacketArrivalRate(long rate, long linkCapacity){ + //see spec p. 14. + if(packetArrivalRate>0)packetArrivalRate=(packetArrivalRate*7+rate)/8; + else packetArrivalRate=rate; + if(estimatedLinkCapacity>0)estimatedLinkCapacity=(estimatedLinkCapacity*7+linkCapacity)/8; + else estimatedLinkCapacity=linkCapacity; } + public long getPacketArrivalRate() { + return packetArrivalRate; + } + + public long getEstimatedLinkCapacity() { + return estimatedLinkCapacity; + } + /* (non-Javadoc) * @see udt.CongestionControl#getSendInterval() */ public double getSendInterval(){ - return packetSendingPeriod ; + return packetSendingPeriod; } /** @@ -96,7 +108,7 @@ * @return */ public long getCongestionWindowSize(){ - return 2048;//congestionWindowSize; + return congestionWindowSize; } /* (non-Javadoc) @@ -109,6 +121,7 @@ //1.if it is in slow start phase,set the congestion window size //to the product of packet arrival rate and(rtt +SYN) double A=packetArrivalRate*(roundTripTime+Util.getSYNTime()); + //System.out.println("rate "+packetArrivalRate+" rtt "+roundTripTime+" A: "+A); if(slowStartPhase){ congestionWindowSize=16; slowStartPhase=false; @@ -120,26 +133,26 @@ //4.compute the number of sent packets to be increase in the next SYN period //and update the send intervall if(estimatedLinkCapacity<= packetArrivalRate){ - numOfIncreasingPacket= 1/maxSegmentSize; + numOfIncreasingPacket= 1.0/maxSegmentSize; }else{ numOfIncreasingPacket=computeNumOfIncreasingPacket(); } //4.update the send period : - packetSendingPeriod=packetSendingPeriod*Util.getSYNTimeSeconds()/ - (packetSendingPeriod*numOfIncreasingPacket+Util.getSYNTimeSeconds()); + double factor=Util.getSYNTimeD()/(packetSendingPeriod*numOfIncreasingPacket+Util.getSYNTimeD()); + packetSendingPeriod=packetSendingPeriod*factor; statistics.setSendPeriod(packetSendingPeriod); } - final double Beta=0.0000015/UDPEndPoint.DATAGRAM_SIZE; + //see spec page 16 + final double BetaDivPS=0.0000015/UDPEndPoint.DATAGRAM_SIZE; private double computeNumOfIncreasingPacket (){ - long B,C,S; - B=estimatedLinkCapacity; - C=packetArrivalRate; - S=UDPEndPoint.DATAGRAM_SIZE; - - double logBase10=Math.log10( S*(B-C)*8 ); - double power10 = Math.pow( 10.0,Math.ceil (logBase10) )* Beta; - double inc = Math.max(power10, 1/S); + long B=estimatedLinkCapacity; + double C=1.0/packetSendingPeriod; + if(B<=C)return C; + long PS=UDPEndPoint.DATAGRAM_SIZE; + double exp=Math.ceil(Math.log10((B-C)*PS*8)); + double power10 = Math.pow( 10.0, exp)* BetaDivPS; + double inc = Math.max(power10, 1/PS); return inc; } @@ -164,6 +177,7 @@ return; } + //start new congestion epoch if(firstBiggestlossSeqNo>lastDecreaseSeqNo){ // 2)If this NAK starts a new congestion epoch Modified: udt-java/trunk/src/main/java/udt/UDTReceiver.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-04-16 21:05:13 UTC (rev 18) +++ udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-04-20 20:17:07 UTC (rev 19) @@ -81,8 +81,8 @@ private final PacketHistoryWindow packetHistoryWindow; //for storing the arrival time of the last received data packet - private long lastDataPacketArrivalTime=0; - + private volatile long lastDataPacketArrivalTime=0; + //largest received data packet sequence number(LRSN) private volatile long largestReceivedSeqNumber=0; @@ -90,7 +90,7 @@ //last Ack number private long lastAckNumber=0; - + //largest Ack number ever acknowledged by ACK2 private volatile long largestAcknowledgedAckNumber=-1; @@ -125,24 +125,24 @@ private long nextEXP; //microseconds to next EXP event - private long EXP_INTERVAL=1000000; + private long EXP_INTERVAL=2*Util.getSYNTime(); //buffer size for storing data private final long bufferSize; - + //stores packets to be sent private final BlockingQueue<UDTPacket>handoffQueue=new ArrayBlockingQueue<UDTPacket>(32); private Thread receiverThread; private volatile boolean stopped=false; - + /** * if set to true connections will not expire, but will only be * closed by a Shutdown message */ public static boolean connectionExpiryDisabled=false; - + /** * create a receiver with a valid {@link UDTSession} * @param session @@ -157,8 +157,8 @@ receiverLossList = new ReceiverLossList(); packetPairWindow = new PacketPairWindow(16); nextACK=Util.getCurrentTime()+ACK_INTERVAL; - nextNAK=Util.getCurrentTime()+NAK_INTERVAL; - nextEXP=Util.getCurrentTime()+EXP_INTERVAL; + nextNAK=(long)(Util.getCurrentTime()+1.5*NAK_INTERVAL); + nextEXP=Util.getCurrentTime()+2*EXP_INTERVAL; bufferSize=session.getReceiveBufferSize(); start(); } @@ -194,7 +194,6 @@ * see specification P11. */ public void receiverAlgorithm()throws InterruptedException,IOException{ - //check ACK timer long currentTime=Util.getCurrentTime(); if(nextACK<currentTime){ @@ -254,7 +253,7 @@ return; }else if (ackNumber==lastAckNumber) { //or it is equals to the ackNumber in the last ACK - //and the time interval between these two ACK packets ??? + //and the time interval between these two ACK packets //is less than 2 RTTs,do not send(stop) long timeOfLastSentAck=ackHistoryWindow.getTime(lastAckNumber); if(Util.getCurrentTime()-timeOfLastSentAck< 2*roundTripTime){ @@ -265,6 +264,7 @@ //if this ACK is not triggered by ACK timers,send out a light Ack and stop. if(!isTriggeredByTimer){ ackSeqNumber=sendLightAcknowledgment(ackNumber); + return; } else{ //pack the packet speed and link capacity into the ACK packet and send it out. @@ -320,11 +320,11 @@ Acknowledgment2 ack2=(Acknowledgment2)p; onAck2PacketReceived(ack2); } - + else if (p instanceof Shutdown){ onShutdown(); } - + //other packet types? } @@ -333,7 +333,7 @@ public static int dropRate=0; //number of received data packets private int n=0; - + protected void onDataPacketReceived(DataPacket dp)throws IOException{ long currentSequenceNumber = dp.getPacketSequenceNumber(); //check whether to drop this packet @@ -342,13 +342,13 @@ logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); return; } - + long currentDataPacketArrivalTime = Util.getCurrentTime(); /*(4).if the seqNo of the current data packet is 16n+1,record the time interval between this packet and the last data packet in the packet pair window*/ - if((currentSequenceNumber%16)==1){ + if((currentSequenceNumber%16)==1 && lastDataPacketArrivalTime>0){ long interval=currentDataPacketArrivalTime -lastDataPacketArrivalTime; packetPairWindow.add(interval); } @@ -362,7 +362,7 @@ //no left space in application data buffer->drop this packet return; } - + //(6).number of detected lossed packet /*(6.a).if the number of the current data packet is greater than LSRN+1, put all the sequence numbers between (but excluding) these two values @@ -378,9 +378,9 @@ receiverLossList.remove(currentSequenceNumber); } } - + statistics.incNumberOfReceivedDataPackets(); - + //(7).Update the LRSN if(currentSequenceNumber>largestReceivedSeqNumber){ largestReceivedSeqNumber=currentSequenceNumber; @@ -410,7 +410,7 @@ protected void sendNAK(List<Long>sequenceNumbers)throws IOException{ if(sequenceNumbers.size()==0)return; NegativeAcknowledgement nAckPacket= new NegativeAcknowledgement(); - + nAckPacket.addLossInfo(sequenceNumbers); nAckPacket.setSession(session); nAckPacket.setDestinationID(session.getDestination().getSocketID()); @@ -428,14 +428,14 @@ protected long sendAcknowledgment(long ackNumber)throws IOException{ Acknowledgement acknowledgmentPkt = buildLightAcknowledgement(ackNumber); //set the estimate link capacity - estimateLinkCapacity=(long)packetPairWindow.getEstimatedLinkCapacity(); + estimateLinkCapacity=packetPairWindow.getEstimatedLinkCapacity(); acknowledgmentPkt.setEstimatedLinkCapacity(estimateLinkCapacity); //set the packet arrival rate packetArrivalSpeed=(long)packetHistoryWindow.getPacketArrivalSpeed(); acknowledgmentPkt.setPacketReceiveRate(packetArrivalSpeed); - + endpoint.doSend(acknowledgmentPkt); - + statistics.incNumberOfACKSent(); statistics.setPacketArrivalRate(packetArrivalSpeed, estimateLinkCapacity); return acknowledgmentPkt.getAckSequenceNumber(); @@ -452,10 +452,10 @@ acknowledgmentPkt.setRoundTripTimeVar(roundTripTimeVar); //set the buffer size acknowledgmentPkt.setBufferSize(bufferSize); - + acknowledgmentPkt.setDestinationID(session.getDestination().getSocketID()); acknowledgmentPkt.setSession(session); - + return acknowledgmentPkt; } @@ -469,21 +469,24 @@ rtt) / 8. <br/> 4) Update RTTVar by: RTTVar = (RTTVar * 3 + abs(RTT - rtt)) / 4. <br/> 5) Update both ACK and NAK period to 4 * RTT + RTTVar + SYN. <br/> - */ + */ protected void onAck2PacketReceived(Acknowledgment2 ack2){ AckHistoryEntry entry=ackHistoryWindow.getEntry(ack2.getAckSequenceNumber()); if(entry!=null){ long ackNumber=entry.getAckNumber(); largestAcknowledgedAckNumber=Math.max(ackNumber, largestAcknowledgedAckNumber); + long rtt=entry.getAge(); - roundTripTime = (roundTripTime*7 + rtt)/8; + if(roundTripTime>0)roundTripTime = (roundTripTime*7 + rtt)/8; + else roundTripTime = rtt; roundTripTimeVar = (roundTripTimeVar* 3 + Math.abs(roundTripTimeVar- rtt)) / 4; + ACK_INTERVAL=4*roundTripTime+roundTripTimeVar+Util.getSYNTime(); NAK_INTERVAL=ACK_INTERVAL; statistics.setRTT(roundTripTime, roundTripTimeVar); } } - + protected void sendKeepAlive()throws IOException{ KeepAlive ka=new KeepAlive(); ka.setDestinationID(session.getDestination().getSocketID()); @@ -504,12 +507,13 @@ nextEXP=Util.getCurrentTime()+EXP_INTERVAL; expCount=0; } - + protected void onShutdown()throws IOException{ stop(); } public void stop()throws IOException{ + System.out.println("STOP"); stopped=true; session.getSocket().close(); //stop our sender as well @@ -522,5 +526,5 @@ sb.append("LossList: "+receiverLossList); return sb.toString(); } - + } Modified: udt-java/trunk/src/main/java/udt/UDTSender.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSender.java 2010-04-16 21:05:13 UTC (rev 18) +++ udt-java/trunk/src/main/java/udt/UDTSender.java 2010-04-20 20:17:07 UTC (rev 19) @@ -68,9 +68,9 @@ private final UDPEndPoint endpoint; private final UDTSession session; - + private final UDTStatistics statistics; - + //sendLossList store the sequence numbers of lost packets //feed back by the receiver through NAK pakets private final SenderLossList senderLossList; @@ -96,25 +96,31 @@ //last acknowledge number, initialised to the initial sequence number private long lastAckSequenceNumber; + //instant when the last packet was sent + private long lastSentTime=0; + //size of the send queue - public static final int MAX_SIZE=1024; + public final int sendQueueLength; private volatile boolean stopped=false; - private volatile AtomicReference<CountDownLatch> latchRef=new AtomicReference<CountDownLatch>(); - + private volatile AtomicReference<CountDownLatch> waitForAckLatch=new AtomicReference<CountDownLatch>(); + + private volatile AtomicReference<CountDownLatch> waitForSeqAckLatch=new AtomicReference<CountDownLatch>(); + public UDTSender(UDTSession session,UDPEndPoint endpoint){ + if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); this.endpoint= endpoint; this.session=session; - this.statistics=session.getStatistics(); - if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); + statistics=session.getStatistics(); + sendQueueLength=64;//session.getFlowWindowSize(); senderLossList=new SenderLossList(); - sendBuffer=new ConcurrentHashMap<Long, DataPacket>(MAX_SIZE,0.75f,2); - sendQueue = new LinkedBlockingQueue<DataPacket>(MAX_SIZE); + sendBuffer=new ConcurrentHashMap<Long, DataPacket>(sendQueueLength,0.75f,2); + sendQueue = new LinkedBlockingQueue<DataPacket>(sendQueueLength); lastAckSequenceNumber=session.getInitialSequenceNumber(); - - latchRef.set(new CountDownLatch(1)); + waitForAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.set(new CountDownLatch(1)); start(); } @@ -130,6 +136,7 @@ ie.printStackTrace(); } catch(IOException ex){ + ex.printStackTrace(); logger.log(Level.SEVERE,"",ex); } logger.info("STOPPING SENDER for "+session); @@ -195,20 +202,25 @@ } protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ - latchRef.get().countDown(); + waitForAckLatch.get().countDown(); + waitForSeqAckLatch.get().countDown(); + CongestionControl cc=session.getCongestionControl(); - if(acknowledgement.getPacketReceiveRate()>0){ - long rtt=acknowledgement.getRoundTripTime(); + long rtt=acknowledgement.getRoundTripTime(); + if(rtt>0){ long rttVar=acknowledgement.getRoundTripTimeVar(); cc.setRTT(rtt,rttVar); - long rate=acknowledgement.getPacketReceiveRate(); - long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); - cc.setPacketArrivalRate(rate, linkCapacity); statistics.setRTT(rtt, rttVar); - statistics.setPacketArrivalRate(rate, linkCapacity); } - cc.onACK(acknowledgement.getAckNumber()); + long rate=acknowledgement.getPacketReceiveRate(); + if(rate>0){ + long linkCapacity=acknowledgement.getEstimatedLinkCapacity(); + cc.updatePacketArrivalRate(rate, linkCapacity); + statistics.setPacketArrivalRate(cc.getPacketArrivalRate(), cc.getEstimatedLinkCapacity()); + } + long ackNumber=acknowledgement.getAckNumber(); + cc.onACK(ackNumber); //need to remove all sequence numbers up the ack number from the sendBuffer boolean removed=false; for(long s=lastAckSequenceNumber;s<ackNumber;s++){ @@ -224,7 +236,6 @@ sendAck2(ackNumber); statistics.incNumberOfACKReceived(); statistics.storeParameters(); - } /** @@ -232,9 +243,14 @@ * @param nak */ protected void onNAKPacketReceived(NegativeAcknowledgement nak){ + waitForAckLatch.get().countDown(); + for(Integer i: nak.getDecodedLossInfo()){ senderLossList.insert(new SenderLossListEntry(i)); } + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets: "+nak.getDecodedLossInfo()); + } session.getCongestionControl().onNAK(nak.getDecodedLossInfo()); //reset EXP. EXP is in the receiver currently.... maybe move to SOCKET? session.getSocket().getReceiver().resetEXPTimer(); @@ -253,7 +269,6 @@ protected void sendAck2(long ackSequenceNumber)throws IOException{ Acknowledgment2 ackOfAckPkt = new Acknowledgment2(); - ackOfAckPkt.setDestinationID(0L); ackOfAckPkt.setAckSequenceNumber(ackSequenceNumber); ackOfAckPkt.setSession(session); ackOfAckPkt.setDestinationID(session.getDestination().getSocketID()); @@ -263,7 +278,6 @@ /** * sender algorithm */ - long lastSentTime=0; public void senderAlgorithm()throws InterruptedException, IOException{ //if the sender's loss list is not empty SenderLossListEntry entry=senderLossList.getFirstEntry(); @@ -287,34 +301,37 @@ }catch (Exception e) { logger.log(Level.WARNING,"",e); } + // return; } - else { - //if the number of unacknowledged data packets does not exceed the congestion - //and the flow window sizes, pack a new packet - int unAcknowledged=unacknowledged.get(); - if(unAcknowledged<session.getCongestionControl().getCongestionWindowSize() - && unAcknowledged<session.getFlowWindowSize()){ - double snd=session.getCongestionControl().getSendInterval(); - if(Util.getCurrentTime()-lastSentTime<snd){ - statistics.incNumberOfCCSlowDownEvents(); - return; - } - DataPacket dp=sendQueue.poll(100,TimeUnit.MILLISECONDS); - if(dp!=null){ - lastSentTime=Util.getCurrentTime(); - send(dp); - largestSentSequenceNumber=dp.getPacketSequenceNumber(); - } - }else{ - //should we *really* wait for an ack?! - if(unAcknowledged>=session.getCongestionControl().getCongestionWindowSize()){ - statistics.incNumberOfCCWindowExceededEvents(); - } + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + double snd=session.getCongestionControl().getSendInterval(); + if(unAcknowledged<session.getCongestionControl().getCongestionWindowSize() + && unAcknowledged<session.getFlowWindowSize()){ + if(lastSentTime>0 && Util.getCurrentTime()-lastSentTime<snd){ + statistics.incNumberOfCCSlowDownEvents(); + return; } - Thread.yield(); + if(sendQueue.size()==0){ + Thread.yield(); + return; + } + DataPacket dp=sendQueue.poll(20,TimeUnit.MILLISECONDS); + if(dp!=null){ + send(dp); + lastSentTime=Util.getCurrentTime(); + largestSentSequenceNumber=dp.getPacketSequenceNumber(); + } + }else{ + //should we *really* wait for an ack?! + if(unAcknowledged>=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + Thread.sleep(1); + //waitForAck(); } - } /** @@ -324,7 +341,6 @@ synchronized (sendLock) { for(Long l: sendBuffer.keySet()){ senderLossList.insert(new SenderLossListEntry(l)); - logger.fine("NO ACK FOR "+l); } } } @@ -354,7 +370,7 @@ public long getLastAckSequenceNumber(){ return lastAckSequenceNumber; } - + boolean haveAcknowledgementFor(long sequenceNumber){ return sequenceNumber<=lastAckSequenceNumber; } @@ -366,19 +382,29 @@ boolean haveLostPackets(){ return senderLossList.isEmpty(); } - + /** - * wait for the next acknowledge + * wait until the given sequence number has been acknowledged + * * @throws InterruptedException */ public synchronized void waitForAck(long sequenceNumber)throws InterruptedException{ while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ - latchRef.set(new CountDownLatch(1)); - latchRef.get().await(10, TimeUnit.MILLISECONDS); + waitForSeqAckLatch.set(new CountDownLatch(1)); + waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); } } - + /** + * wait for the next acknowledge + * @throws InterruptedException + */ + public synchronized void waitForAck()throws InterruptedException{ + waitForAckLatch.set(new CountDownLatch(1)); + waitForAckLatch.get().await(1000, TimeUnit.MILLISECONDS); + } + + public void stop(){ stopped=true; } Modified: udt-java/trunk/src/main/java/udt/UDTSession.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSession.java 2010-04-16 21:05:13 UTC (rev 18) +++ udt-java/trunk/src/main/java/udt/UDTSession.java 2010-04-20 20:17:07 UTC (rev 19) @@ -68,7 +68,7 @@ * flow window size, i.e. how many data packets are * in-flight at a single time */ - protected int flowWindowSize=64; + protected int flowWindowSize=1024; /** * remote UDT entity (address and socket ID) Modified: udt-java/trunk/src/main/java/udt/UDTSocket.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSocket.java 2010-04-16 21:05:13 UTC (rev 18) +++ udt-java/trunk/src/main/java/udt/UDTSocket.java 2010-04-20 20:17:07 UTC (rev 19) @@ -170,6 +170,7 @@ int chunksize=session.getDatagramSize()-24;//need some bytes for the header ByteBuffer bb=ByteBuffer.wrap(data,offset,length); long seqNo=0; + int i=0; while(bb.remaining()>0){ int len=Math.min(bb.remaining(),chunksize); byte[]chunk=new byte[len]; @@ -182,8 +183,9 @@ packet.setData(chunk); //put the packet into the send queue while(!sender.sendUdtPacket(packet, timeout, units)){ - System.out.println("SOCKET WAIT"); + Thread.sleep(1); } + i++; } if(length>0)active=true; } Modified: udt-java/trunk/src/main/java/udt/packets/DataPacket.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/DataPacket.java 2010-04-16 21:05:13 UTC (rev 18) +++ udt-java/trunk/src/main/java/udt/packets/DataPacket.java 2010-04-20 20:17:07 UTC (rev 19) @@ -64,7 +64,7 @@ } void decode(byte[]encodedData,int length){ - packetSequenceNumber =PacketUtil.decode(encodedData, 0); + packetSequenceNumber=PacketUtil.decode(encodedData, 0); messageNumber=PacketUtil.decode(encodedData, 4); timeStamp=PacketUtil.decode(encodedData, 8); destinationID=PacketUtil.decode(encodedData, 12); Modified: udt-java/trunk/src/main/java/udt/packets/PacketFactory.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/PacketFactory.java 2010-04-16 21:05:13 UTC (rev 18) +++ udt-java/trunk/src/main/java/udt/packets/PacketFactory.java 2010-04-20 20:17:07 UTC (rev 19) @@ -76,31 +76,31 @@ packet=new ConnectionHandshake(controlInformation); } //TYPE 0001:1 - if(ControlPacketType.KEEP_ALIVE.ordinal()==pktType){ + else if(ControlPacketType.KEEP_ALIVE.ordinal()==pktType){ packet=new KeepAlive(); } //TYPE 0010:2 - if(ControlPacketType.ACK.ordinal()==pktType){ + else if(ControlPacketType.ACK.ordinal()==pktType){ packet=new Acknowledgement(controlInformation); } //TYPE 0011:3 - if(ControlPacketType.NAK.ordinal()==pktType){ + else if(ControlPacketType.NAK.ordinal()==pktType){ packet=new NegativeAcknowledgement(controlInformation); } //TYPE 0101:5 - if(ControlPacketType.SHUTDOWN.ordinal()==pktType){ + else if(ControlPacketType.SHUTDOWN.ordinal()==pktType){ packet=new Shutdown(); } //TYPE 0110:6 - if(ControlPacketType.ACK2.ordinal()==pktType){ + else if(ControlPacketType.ACK2.ordinal()==pktType){ packet=new Acknowledgment2(controlInformation); } //TYPE 0111:7 - if(ControlPacketType.MESSAGE_DROP_REQUEST.ordinal()==pktType){ + else if(ControlPacketType.MESSAGE_DROP_REQUEST.ordinal()==pktType){ packet=new MessageDropRequest(controlInformation); } //TYPE 1111:8 - if(ControlPacketType.USER_DEFINED.ordinal()==pktType){ + else if(ControlPacketType.USER_DEFINED.ordinal()==pktType){ packet=new UserDefined(controlInformation); } Modified: udt-java/trunk/src/main/java/udt/packets/PacketUtil.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/PacketUtil.java 2010-04-16 21:05:13 UTC (rev 18) +++ udt-java/trunk/src/main/java/udt/packets/PacketUtil.java 2010-04-20 20:17:07 UTC (rev 19) @@ -112,71 +112,5 @@ return result; } - - /** - * Gibt einen int-Wert zurueck, der das Byte im Bereich von 0 bis - * 255 repraesentiert (negative Bytes werden umgewandelt) - *@param b zu konvertierendes Byte - *@return positiver Byte-Wert - */ - public static int castPositive(byte b) - { - return b < 0 ? b + 256 : b; - } - - /** - * Die Methode erstellt aus dem gegebenen byte-array eine Dezimalzahl vom - * Typ long, indem jedes p als Zahl zur Basis 256 interpretiert wird - * (gelesen: stelle 0 = b[b.length-1] ...) - *@param b umzuwandelndes Byte-Array - *@return entsprechende long-Zahl - */ - public static long toDecValue(byte[] b) { - if(b != null) - { - long result = 0; - for (int i = 0; i < b.length; i++) { - long l = castPositive(b[i]); - result += l * Math.pow(256, b.length - i - 1); - } - return result; - } - return 0; - } - -// private Hilfsmethoden - /*Hilfsmethode zur Darstellung des 2-stelligen hexadezimalen Werts von b als String. - *Negative byte-Werte werden ueber einen int-cast (und "Betrag+127") in positive Zahlen konvertiert. - *(Anomalie: grosse byte-Werte werden im IEEE-2er-Komplement dargestellt?) - */ - public static String toHexString(byte b) - { - String hex = Integer.toHexString(castPositive(b)).toUpperCase(); - if(hex.length() == 1) hex = "0" + hex; - return hex; - } - - public static long convertByteArrayToLong(byte[] buffer) { - if (buffer.length != 4) { - throw new IllegalArgumentException("buffer length must be 4 bytes!"); - } - long - value = buffer[0] << 24; - value |= buffer[1] << 16; - value |= buffer[2] << 8; - value |= buffer[3]; - return value; - } - - public static byte[] convertIntToByteArray(int val) { - byte[] buffer = new byte[4]; - - buffer[0] = (byte) (val >> 24); - buffer[1] = (byte) (val >> 16); - buffer[2] = (byte) (val >> 8); - buffer[3] = (byte) val; - - return buffer; - } - + } Modified: udt-java/trunk/src/main/java/udt/receiver/PacketPairWindow.java =================================================================== --- udt-java/trunk/src/main/java/udt/receiver/PacketPairWindow.java 2010-04-16 21:05:13 UTC (rev 18) +++ udt-java/trunk/src/main/java/udt/receiver/PacketPairWindow.java 2010-04-20 20:17:07 UTC (rev 19) @@ -58,11 +58,27 @@ */ public double computeMedianTimeInterval(){ int num=haveOverflow?max:Math.min(max, position); - double total=0; + double median=0; for(int i=0; i<num;i++){ - total+=circularArray.get(i).doubleValue(); + median+=circularArray.get(i).doubleValue(); } - return total/num; + median=median/num; + //median filtering + double upper=median*8; + double lower=median/8; + double total = 0; + double val=0; + int count=0; + for(int i=0; i<num;i++){ + val=circularArray.get(i).doubleValue(); + if(val<upper && val>lower){ + total+=val; + count++; + } + } + median=total/count; + //System.out.println("median "+median); + return median; } /** @@ -70,7 +86,8 @@ * packet pair window * @return number of packets per second */ - public double getEstimatedLinkCapacity(){ - return 1e6/computeMedianTimeInterval(); + public long getEstimatedLinkCapacity(){ + long res=(long)Math.ceil(1000000/computeMedianTimeInterval()); + return res; } } Modified: udt-java/trunk/src/main/java/udt/sender/SenderLossList.java =================================================================== --- udt-java/trunk/src/main/java/udt/sender/SenderLossList.java 2010-04-16 21:05:13 UTC (rev 18) +++ udt-java/trunk/src/main/java/udt/sender/SenderLossList.java 2010-04-20 20:17:07 UTC (rev 19) @@ -55,15 +55,7 @@ } public void remove(long seqNo){ - Iterator<SenderLossListEntry>iterator=backingList.iterator(); - while(iterator.hasNext()){ - SenderLossListEntry e=iterator.next(); - if(e.getSequenceNumber()==seqNo){ - iterator.remove(); - return; - } - } - //backingList.remove(new SenderLossListEntry(seqNo)); + backingList.remove(new SenderLossListEntry(seqNo)); } /** Modified: udt-java/trunk/src/main/java/udt/util/Util.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/Util.java 2010-04-16 21:05:13 UTC (rev 18) +++ udt-java/trunk/src/main/java/udt/util/Util.java 2010-04-20 20:17:07 UTC (rev 19) @@ -47,7 +47,7 @@ public class Util { /** - * get the current system time in microseconds + * get the current timer value in microseconds * @return */ public static long getCurrentTime(){ @@ -61,6 +61,11 @@ public static long getSYNTime(){ return 10000; } + + public static double getSYNTimeD(){ + return 10000.0; + } + /** * get the SYN time in seconds. The SYN time is 0.01 seconds = 10000 microseconds * @return Modified: udt-java/trunk/src/test/java/udt/NullCongestionControl.java =================================================================== --- udt-java/trunk/src/test/java/udt/NullCongestionControl.java 2010-04-16 21:05:13 UTC (rev 18) +++ udt-java/trunk/src/test/java/udt/NullCongestionControl.java 2010-04-20 20:17:07 UTC (rev 19) @@ -39,10 +39,18 @@ public void onTimeout() { } - public void setPacketArrivalRate(long rate, long linkCapacity) { + public void updatePacketArrivalRate(long rate, long linkCapacity) { } public void setRTT(long rtt, long rttVar) { } + public long getEstimatedLinkCapacity() { + return 0; + } + + public long getPacketArrivalRate() { + return 0; + } + } Modified: udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-04-16 21:05:13 UTC (rev 18) +++ udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-04-20 20:17:07 UTC (rev 19) @@ -7,12 +7,10 @@ import java.util.logging.Level; import java.util.logging.Logger; -import udt.NullCongestionControl; import udt.UDTClient; import udt.UDTInputStream; import udt.UDTReceiver; import udt.UDTServerSocket; -import udt.UDTSession; import udt.UDTSocket; import udt.UDTTestBase; import udt.util.UDTStatistics; @@ -22,7 +20,7 @@ boolean running=false; //how many - int num_packets=100; + int num_packets=300; //how large is a single packet int size=1*1024*1024; @@ -33,8 +31,7 @@ public void test1()throws Exception{ Logger.getLogger("udt").setLevel(Level.INFO); - System.setProperty(UDTSession.CC_CLASS, NullCongestionControl.class.getName()); - + //System.setProperty(UDTSession.CC_CLASS, NullCongestionControl.class.getName()); UDTReceiver.dropRate=0; TIMEOUT=Integer.MAX_VALUE; UDTReceiver.connectionExpiryDisabled=true; @@ -81,7 +78,7 @@ System.out.println("MD5 hash of data received: "+md5_received); System.out.println(client.getStatistics()); - assertEquals(md5_sent,md5_received); + //assertEquals(md5_sent,md5_received); //store stat history to csv file client.getStatistics().writeParameterHistory(File.createTempFile("/udtstats-",".csv")); @@ -112,7 +109,7 @@ c=is.read(buf); if(c<0)break; else{ - md5.update(buf, 0, c); + //md5.update(buf, 0, c); total+=c; Thread.yield(); } Modified: udt-java/trunk/src/test/java/udt/performance/UDPTest.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/UDPTest.java 2010-04-16 21:05:13 UTC (rev 18) +++ udt-java/trunk/src/test/java/udt/performance/UDPTest.java 2010-04-20 20:17:07 UTC (rev 19) @@ -6,15 +6,16 @@ import java.util.Random; import junit.framework.TestCase; +import udt.UDPEndPoint; /** * send some data over a UDP connection and measure performance */ public class UDPTest extends TestCase { - final int num_packets=100*1000; - final int packetSize=1500; - + final int num_packets=5*1000; + final int packetSize=UDPEndPoint.DATAGRAM_SIZE; + public void test1()throws Exception{ runServer(); //client socket @@ -42,11 +43,11 @@ System.out.println("Rate "+num_packets+" packets/sec"); System.out.println("Server received: "+total); } - + int N=0; long total=0; volatile boolean serverRunning=true; - + private void runServer()throws Exception{ //server socket final DatagramSocket serverSocket=new DatagramSocket(65321); @@ -56,11 +57,15 @@ try{ byte[]buf=new byte[packetSize]; DatagramPacket dp=new DatagramPacket(buf,buf.length); + long start=System.currentTimeMillis(); while(true){ serverSocket.receive(dp); total+=dp.getLength(); if(total==N)break; } + long end=System.currentTimeMillis(); + System.out.println("Server time: "+(end-start)+" ms."); + } catch(Exception e){ e.printStackTrace(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2010-04-20 21:21:21
|
Revision: 20 http://udt-java.svn.sourceforge.net/udt-java/?rev=20&view=rev Author: bschuller Date: 2010-04-20 21:21:15 +0000 (Tue, 20 Apr 2010) Log Message: ----------- disable connection expiry Modified Paths: -------------- udt-java/trunk/src/main/java/udt/UDTReceiver.java udt-java/trunk/src/main/java/udt/util/ReceiveFile.java udt-java/trunk/src/main/java/udt/util/SendFile.java udt-java/trunk/src/test/java/udt/TestSendFileReceiveFile.java Modified: udt-java/trunk/src/main/java/udt/UDTReceiver.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-04-20 20:17:07 UTC (rev 19) +++ udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-04-20 21:21:15 UTC (rev 20) @@ -125,7 +125,7 @@ private long nextEXP; //microseconds to next EXP event - private long EXP_INTERVAL=2*Util.getSYNTime(); + private long EXP_INTERVAL=10*Util.getSYNTime(); //buffer size for storing data private final long bufferSize; @@ -513,7 +513,6 @@ } public void stop()throws IOException{ - System.out.println("STOP"); stopped=true; session.getSocket().close(); //stop our sender as well Modified: udt-java/trunk/src/main/java/udt/util/ReceiveFile.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/ReceiveFile.java 2010-04-20 20:17:07 UTC (rev 19) +++ udt-java/trunk/src/main/java/udt/util/ReceiveFile.java 2010-04-20 21:21:15 UTC (rev 20) @@ -40,6 +40,7 @@ import udt.UDTClient; import udt.UDTInputStream; import udt.UDTOutputStream; +import udt.UDTReceiver; /** * helper class for receiving a single file via UDT @@ -66,6 +67,7 @@ public void run(){ configure(); try{ + UDTReceiver.connectionExpiryDisabled=true; InetAddress myHost=localIP!=null?InetAddress.getByName(localIP):InetAddress.getLocalHost(); UDTClient client=localPort!=-1?new UDTClient(myHost,localPort):new UDTClient(myHost); client.connect(serverHost, serverPort); Modified: udt-java/trunk/src/main/java/udt/util/SendFile.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/SendFile.java 2010-04-20 20:17:07 UTC (rev 19) +++ udt-java/trunk/src/main/java/udt/util/SendFile.java 2010-04-20 21:21:15 UTC (rev 20) @@ -42,6 +42,7 @@ import udt.UDTInputStream; import udt.UDTOutputStream; +import udt.UDTReceiver; import udt.UDTServerSocket; import udt.UDTSocket; import udt.packets.PacketUtil; @@ -72,6 +73,7 @@ public void run(){ configure(); try{ + UDTReceiver.connectionExpiryDisabled=true; InetAddress myHost=localIP!=null?InetAddress.getByName(localIP):InetAddress.getLocalHost(); UDTServerSocket server=new UDTServerSocket(myHost,serverPort); while(true){ @@ -134,7 +136,7 @@ bb.get(fileName); File file=new File(new String(fileName)); - System.out.println("[SendFile] File requested: "+file.getPath()); + System.out.println("[SendFile] File requested: '"+file.getPath()+"'"); FileInputStream fis=new FileInputStream(file); try{ Modified: udt-java/trunk/src/test/java/udt/TestSendFileReceiveFile.java =================================================================== --- udt-java/trunk/src/test/java/udt/TestSendFileReceiveFile.java 2010-04-20 20:17:07 UTC (rev 19) +++ udt-java/trunk/src/test/java/udt/TestSendFileReceiveFile.java 2010-04-20 21:21:15 UTC (rev 20) @@ -13,7 +13,10 @@ public void test1()throws Exception{ runServer(); - while(!serverStarted)Thread.sleep(100); + do{ + Thread.sleep(500); + }while(!serverStarted); + File f=new File("src/test/java/datafile"); File tmp=File.createTempFile("udtest-", null); @@ -28,9 +31,9 @@ private void runServer(){ Runnable r=new Runnable(){ public void run(){ - serverStarted=true; String []args=new String[]{"65321"}; try{ + serverStarted=true; SendFile.main(args); }catch(Exception ex){ ex.printStackTrace(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2010-04-21 15:45:06
|
Revision: 21 http://udt-java.svn.sourceforge.net/udt-java/?rev=21&view=rev Author: bschuller Date: 2010-04-21 15:45:00 +0000 (Wed, 21 Apr 2010) Log Message: ----------- rate control stuff --- still not so great IMO Modified Paths: -------------- udt-java/trunk/src/main/java/udt/ClientSession.java udt-java/trunk/src/main/java/udt/UDTCongestionControl.java udt-java/trunk/src/main/java/udt/UDTReceiver.java udt-java/trunk/src/main/java/udt/UDTSender.java udt-java/trunk/src/main/java/udt/receiver/PacketPairWindow.java udt-java/trunk/src/test/java/udt/TestSendFileReceiveFile.java udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java Modified: udt-java/trunk/src/main/java/udt/ClientSession.java =================================================================== --- udt-java/trunk/src/main/java/udt/ClientSession.java 2010-04-20 21:21:15 UTC (rev 20) +++ udt-java/trunk/src/main/java/udt/ClientSession.java 2010-04-21 15:45:00 UTC (rev 21) @@ -107,8 +107,6 @@ } active = true; try{ - //packet received means we should not yet expire - socket.getReceiver().resetEXPTimer(); if(packet.forSender()){ socket.getSender().receive(lastPacket); }else{ Modified: udt-java/trunk/src/main/java/udt/UDTCongestionControl.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTCongestionControl.java 2010-04-20 21:21:15 UTC (rev 20) +++ udt-java/trunk/src/main/java/udt/UDTCongestionControl.java 2010-04-21 15:45:00 UTC (rev 21) @@ -1,12 +1,16 @@ package udt; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import udt.util.UDTStatistics; import udt.util.Util; public class UDTCongestionControl implements CongestionControl { + private static final Logger logger=Logger.getLogger(UDTCongestionControl.class.getName()); + private final UDTSession session; private final UDTStatistics statistics; @@ -49,14 +53,16 @@ long nACKCount=1; //number of decreases in a congestion epoch - long congestionEpochDecreaseCount=1; + long decCount=1; //random threshold on decrease by number of loss events - long decreaseRandom; + long decreaseRandom=1; //average number of NAKs per congestion long averageNACKNum; + boolean loss=false; + public UDTCongestionControl(UDTSession session){ this.session=session; this.statistics=session.getStatistics(); @@ -115,41 +121,65 @@ * @see udt.CongestionControl#onACK(long) */ public void onACK(long ackSeqno){ - //the fixed size of a UDT packet - long maxSegmentSize=UDPEndPoint.DATAGRAM_SIZE; - - //1.if it is in slow start phase,set the congestion window size - //to the product of packet arrival rate and(rtt +SYN) - double A=packetArrivalRate*(roundTripTime+Util.getSYNTime()); - //System.out.println("rate "+packetArrivalRate+" rtt "+roundTripTime+" A: "+A); + //increase window during slow start if(slowStartPhase){ - congestionWindowSize=16; - slowStartPhase=false; - return; + congestionWindowSize+=ackSeqno-lastAckSeqNumber; + lastAckSeqNumber = ackSeqno; + + //but not beyond a maximum size + if(congestionWindowSize>session.getFlowWindowSize()){ + System.out.println("slow start ends on ACK"); + slowStartPhase=false; + if(packetArrivalRate>0){ + packetSendingPeriod=1000000.0/packetArrivalRate; + } + else{ + packetSendingPeriod=(double)congestionWindowSize/(roundTripTime+Util.getSYNTimeD()); + } + } + }else{ + //1.if it is not in slow start phase,set the congestion window size + //to the product of packet arrival rate and(rtt +SYN) + double A=packetArrivalRate/1000000.0*(roundTripTime+Util.getSYNTimeD()); congestionWindowSize=(long)A+16; + if(logger.isLoggable(Level.FINER)){ + logger.finer("receive rate "+packetArrivalRate+" rtt "+roundTripTime+" set to window size: "+(A+16)); + } } + //no rate increase in slow start + if(slowStartPhase)return; + + if(loss){ + loss=false; + return; + } + //4.compute the number of sent packets to be increase in the next SYN period //and update the send intervall - if(estimatedLinkCapacity<= packetArrivalRate){ - numOfIncreasingPacket= 1.0/maxSegmentSize; - }else{ - numOfIncreasingPacket=computeNumOfIncreasingPacket(); - } + numOfIncreasingPacket=computeNumOfIncreasingPacket(); + //4.update the send period : double factor=Util.getSYNTimeD()/(packetSendingPeriod*numOfIncreasingPacket+Util.getSYNTimeD()); - packetSendingPeriod=packetSendingPeriod*factor; + packetSendingPeriod=factor*packetSendingPeriod; + //packetSendingPeriod=0.995*packetSendingPeriod; + //System.out.println("dec snd factor "+factor+" to "+packetSendingPeriod); + statistics.setSendPeriod(packetSendingPeriod); } + private final long PS=UDPEndPoint.DATAGRAM_SIZE; + private final double BetaDivPS=0.0000015/PS; + //see spec page 16 - final double BetaDivPS=0.0000015/UDPEndPoint.DATAGRAM_SIZE; private double computeNumOfIncreasingPacket (){ - long B=estimatedLinkCapacity; - double C=1.0/packetSendingPeriod; - if(B<=C)return C; - long PS=UDPEndPoint.DATAGRAM_SIZE; + //link capacity and sending speed, in packets per second + double B=estimatedLinkCapacity; + double C=1000000.0/packetSendingPeriod; + + if(B<=C)return 1.0/UDPEndPoint.DATAGRAM_SIZE; + double exp=Math.ceil(Math.log10((B-C)*PS*8)); double power10 = Math.pow( 10.0, exp)* BetaDivPS; double inc = Math.max(power10, 1/PS); @@ -160,49 +190,49 @@ * @see udt.CongestionControl#onNAK(java.util.List) */ public void onNAK(List<Integer>lossInfo){ + loss=true; long firstBiggestlossSeqNo=lossInfo.get(lossInfo.size()-1); - long currentMaxSequenceNumber=session.getSocket().getSender().getCurrentSequenceNumber(); - lastAckSeqNumber = currentMaxSequenceNumber; + nACKCount++; /*1) If it is in slow start phase, set inter-packet interval to 1/recvrate. Slow start ends. Stop. */ if(slowStartPhase){ if(packetArrivalRate>0){ - packetSendingPeriod = 1e6/packetArrivalRate; + packetSendingPeriod = 100000.0/packetArrivalRate; } else{ - packetSendingPeriod=congestionWindowSize*(roundTripTime+Util.getSYNTime()); + packetSendingPeriod=congestionWindowSize/(roundTripTime+Util.getSYNTime()); } slowStartPhase = false; return; } - - //start new congestion epoch + long currentMaxSequenceNumber=session.getSocket().getSender().getCurrentSequenceNumber(); + + // 2)If this NAK starts a new congestion epoch if(firstBiggestlossSeqNo>lastDecreaseSeqNo){ - // 2)If this NAK starts a new congestion epoch + // -increase inter-packet interval packetSendingPeriod = Math.ceil(packetSendingPeriod*1.125); // -Update AvgNAKNum(the average number of NAKs per congestion) averageNACKNum = (int)Math.ceil(averageNACKNum*0.875 + nACKCount*0.125); - // -reset NAKCount to 1, + // -reset NAKCount and DecCount to 1, nACKCount=1; - /* - compute DecRandom to a random (average distribution) number between 1 and AvgNAKNum.. */ + decCount=1; + /* - compute DecRandom to a random (average distribution) number between 1 and AvgNAKNum */ decreaseRandom =(int)Math.ceil((averageNACKNum-1)*Math.random()+1); // -Update LastDecSeq lastDecreaseSeqNo = currentMaxSequenceNumber; // -Stop. statistics.setSendPeriod(packetSendingPeriod); - return; } //* 3) If DecCount <= 5, and NAKCount == DecCount * DecRandom: - if(congestionEpochDecreaseCount<=5 && - nACKCount==congestionEpochDecreaseCount*decreaseRandom){ + if(decCount<=5 && nACKCount==decCount*decreaseRandom){ // a. Update SND period: SND = SND * 1.125; packetSendingPeriod = Math.ceil(packetSendingPeriod*1.125); // b. Increase DecCount by 1; - congestionEpochDecreaseCount++; + decCount++; // c. Record the current largest sent sequence number (LastDecSeq). lastDecreaseSeqNo= currentMaxSequenceNumber; statistics.setSendPeriod(packetSendingPeriod); Modified: udt-java/trunk/src/main/java/udt/UDTReceiver.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-04-20 21:21:15 UTC (rev 20) +++ udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-04-21 15:45:00 UTC (rev 21) @@ -110,7 +110,7 @@ long packetArrivalSpeed; //round trip time, calculated from ACK/ACK2 pairs - long roundTripTime=10*Util.getSYNTime(); + long roundTripTime=50*1000; //round trip time variance long roundTripTimeVar=roundTripTime/2; @@ -125,8 +125,13 @@ private long nextEXP; //microseconds to next EXP event - private long EXP_INTERVAL=10*Util.getSYNTime(); + private long EXP_INTERVAL=Util.getSYNTime(); + //instant when the session was created (for expiry checking) + private final long sessionUpSince; + //milliseconds to timeout a new session that stays idle + private final long IDLE_TIMEOUT = 3*60*1000; + //buffer size for storing data private final long bufferSize; @@ -150,6 +155,7 @@ public UDTReceiver(UDTSession session,UDPEndPoint endpoint){ this.endpoint = endpoint; this.session=session; + this.sessionUpSince=System.currentTimeMillis(); this.statistics=session.getStatistics(); if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); ackHistoryWindow = new AckHistoryWindow(16); @@ -295,7 +301,7 @@ UDTSender sender=session.getSocket().getSender(); //put all the unacknowledged packets in the senders loss list sender.putUnacknowledgedPacketsIntoLossList(); - if(expCount>16){ + if(expCount>16 && System.currentTimeMillis()-sessionUpSince > IDLE_TIMEOUT){ if(!connectionExpiryDisabled &&!stopped){ sendShutdown(); stop(); @@ -508,6 +514,10 @@ expCount=0; } + protected void resetEXPCount(){ + expCount=0; + } + protected void onShutdown()throws IOException{ stop(); } Modified: udt-java/trunk/src/main/java/udt/UDTSender.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSender.java 2010-04-20 21:21:15 UTC (rev 20) +++ udt-java/trunk/src/main/java/udt/UDTSender.java 2010-04-21 15:45:00 UTC (rev 21) @@ -96,9 +96,6 @@ //last acknowledge number, initialised to the initial sequence number private long lastAckSequenceNumber; - //instant when the last packet was sent - private long lastSentTime=0; - //size of the send queue public final int sendQueueLength; @@ -199,6 +196,9 @@ NegativeAcknowledgement nak=(NegativeAcknowledgement)p; onNAKPacketReceived(nak); } + else if (p instanceof KeepAlive) { + session.getSocket().getReceiver().resetEXPCount(); + } } protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ @@ -248,14 +248,16 @@ for(Integer i: nak.getDecodedLossInfo()){ senderLossList.insert(new SenderLossListEntry(i)); } - if(logger.isLoggable(Level.FINER)){ - logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets: "+nak.getDecodedLossInfo()); - } session.getCongestionControl().onNAK(nak.getDecodedLossInfo()); - //reset EXP. EXP is in the receiver currently.... maybe move to SOCKET? session.getSocket().getReceiver().resetEXPTimer(); statistics.incNumberOfNAKReceived(); statistics.storeParameters(); + + //if(logger.isLoggable(Level.FINER)){ + System.out.println("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + +"set send period to "+session.getCongestionControl().getSendInterval()); + //} + return; } @@ -279,16 +281,19 @@ * sender algorithm */ public void senderAlgorithm()throws InterruptedException, IOException{ + long iterationStart=Util.getCurrentTime(); //if the sender's loss list is not empty SenderLossListEntry entry=senderLossList.getFirstEntry(); if (entry!=null) { long seqNumber = entry.getSequenceNumber(); + + //TODO //if the current seqNumber is 16n,check the timeOut in the //loss list and send a message drop request. - if((seqNumber%16)==0){ - //TODO + //if((seqNumber%16)==0){ //sendLossList.checkTimeOut(timeToLive); - } + //} + try { //retransmit the packet with the first entry in the list //as sequence number and remove it from the list @@ -307,13 +312,13 @@ //if the number of unacknowledged data packets does not exceed the congestion //and the flow window sizes, pack a new packet int unAcknowledged=unacknowledged.get(); - double snd=session.getCongestionControl().getSendInterval(); + if(unAcknowledged<session.getCongestionControl().getCongestionWindowSize() && unAcknowledged<session.getFlowWindowSize()){ - if(lastSentTime>0 && Util.getCurrentTime()-lastSentTime<snd){ - statistics.incNumberOfCCSlowDownEvents(); - return; - } +// if(lastSentTime>0 && Util.getCurrentTime()-lastSentTime<snd){ +// statistics.incNumberOfCCSlowDownEvents(); +// return; +// } if(sendQueue.size()==0){ Thread.yield(); return; @@ -321,7 +326,6 @@ DataPacket dp=sendQueue.poll(20,TimeUnit.MILLISECONDS); if(dp!=null){ send(dp); - lastSentTime=Util.getCurrentTime(); largestSentSequenceNumber=dp.getPacketSequenceNumber(); } }else{ @@ -332,6 +336,17 @@ Thread.sleep(1); //waitForAck(); } + + //wait + double snd=session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + while(snd-passed>0){ + //busy wait, but we cannot wait with microsecond precision + if(snd-passed>750)Thread.sleep(1); + statistics.incNumberOfCCSlowDownEvents(); + passed=Util.getCurrentTime()-iterationStart; + } + } /** Modified: udt-java/trunk/src/main/java/udt/receiver/PacketPairWindow.java =================================================================== --- udt-java/trunk/src/main/java/udt/receiver/PacketPairWindow.java 2010-04-20 21:21:15 UTC (rev 20) +++ udt-java/trunk/src/main/java/udt/receiver/PacketPairWindow.java 2010-04-21 15:45:00 UTC (rev 21) @@ -35,7 +35,8 @@ import udt.util.CircularArray; /** - * a circular array that records time intervals between two data packets + * a circular array that records time intervals between two probing data packets. + * It is used to determine the estimated link capacity. * @see {@link CircularArray} * */ @@ -63,6 +64,7 @@ median+=circularArray.get(i).doubleValue(); } median=median/num; + //median filtering double upper=median*8; double lower=median/8; @@ -76,9 +78,9 @@ count++; } } - median=total/count; - //System.out.println("median "+median); - return median; + double res=total/count; + //System.out.println("median: "+median+" filtered "+res); + return res; } /** Modified: udt-java/trunk/src/test/java/udt/TestSendFileReceiveFile.java =================================================================== --- udt-java/trunk/src/test/java/udt/TestSendFileReceiveFile.java 2010-04-20 21:21:15 UTC (rev 20) +++ udt-java/trunk/src/test/java/udt/TestSendFileReceiveFile.java 2010-04-21 15:45:00 UTC (rev 21) @@ -18,6 +18,8 @@ }while(!serverStarted); File f=new File("src/test/java/datafile"); + f=new File("/tmp/200MB"); + File tmp=File.createTempFile("udtest-", null); String[] args=new String[]{"localhost","65321",f.getAbsolutePath(),tmp.getAbsolutePath()}; Modified: udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-04-20 21:21:15 UTC (rev 20) +++ udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-04-21 15:45:00 UTC (rev 21) @@ -20,7 +20,7 @@ boolean running=false; //how many - int num_packets=300; + int num_packets=200; //how large is a single packet int size=1*1024*1024; @@ -34,7 +34,7 @@ //System.setProperty(UDTSession.CC_CLASS, NullCongestionControl.class.getName()); UDTReceiver.dropRate=0; TIMEOUT=Integer.MAX_VALUE; - UDTReceiver.connectionExpiryDisabled=true; + //UDTReceiver.connectionExpiryDisabled=true; doTest(); } @@ -109,7 +109,7 @@ c=is.read(buf); if(c<0)break; else{ - //md5.update(buf, 0, c); + md5.update(buf, 0, c); total+=c; Thread.yield(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2010-04-21 20:36:43
|
Revision: 22 http://udt-java.svn.sourceforge.net/udt-java/?rev=22&view=rev Author: bschuller Date: 2010-04-21 20:36:36 +0000 (Wed, 21 Apr 2010) Log Message: ----------- Modified Paths: -------------- udt-java/trunk/src/main/java/udt/UDTCongestionControl.java udt-java/trunk/src/main/java/udt/UDTSender.java udt-java/trunk/src/main/java/udt/receiver/PacketPairWindow.java udt-java/trunk/src/main/java/udt/sender/SenderLossList.java udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java Modified: udt-java/trunk/src/main/java/udt/UDTCongestionControl.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTCongestionControl.java 2010-04-21 15:45:00 UTC (rev 21) +++ udt-java/trunk/src/main/java/udt/UDTCongestionControl.java 2010-04-21 20:36:36 UTC (rev 22) @@ -7,62 +7,61 @@ import udt.util.UDTStatistics; import udt.util.Util; +/** + * default UDT congestion control.<br/> + * + * The algorithm is adapted from the C++ reference implementation. + */ public class UDTCongestionControl implements CongestionControl { private static final Logger logger=Logger.getLogger(UDTCongestionControl.class.getName()); private final UDTSession session; - + private final UDTStatistics statistics; - + //round trip time in microseconds private long roundTripTime=2*Util.getSYNTime(); - + //rate in packets per second private long packetArrivalRate=0; - + //link capacity in packets per second private long estimatedLinkCapacity=0; - - long maxControlWindowSize=128; // Packet sending period = packet send interval, in microseconds private double packetSendingPeriod=1; + // Congestion window size, in packets private long congestionWindowSize=16; - - //number of packets to be increased in the next SYN period - private double numOfIncreasingPacket; - + //last rate increase time (microsecond value) long lastRateIncreaseTime=Util.getCurrentTime(); - + /*if in slow start phase*/ boolean slowStartPhase=true; - + /*last ACKed seq no*/ long lastAckSeqNumber=-1; - + /*max packet seq. no. sent out when last decrease happened*/ private long lastDecreaseSeqNo; - //value of packetSendPeriod when last decrease happened - long lastDecreasePeriod; - //NAK counter - long nACKCount=1; - + private long nACKCount=1; + //number of decreases in a congestion epoch long decCount=1; - + //random threshold on decrease by number of loss events long decreaseRandom=1; - + //average number of NAKs per congestion long averageNACKNum; - boolean loss=false; - + //this flag avoids immediate rate increase after a NAK + private boolean loss=false; + public UDTCongestionControl(UDTSession session){ this.session=session; this.statistics=session.getStatistics(); @@ -108,7 +107,7 @@ public double getSendInterval(){ return packetSendingPeriod; } - + /** * congestionWindowSize * @return @@ -125,7 +124,7 @@ if(slowStartPhase){ congestionWindowSize+=ackSeqno-lastAckSeqNumber; lastAckSeqNumber = ackSeqno; - + //but not beyond a maximum size if(congestionWindowSize>session.getFlowWindowSize()){ System.out.println("slow start ends on ACK"); @@ -137,7 +136,7 @@ packetSendingPeriod=(double)congestionWindowSize/(roundTripTime+Util.getSYNTimeD()); } } - + }else{ //1.if it is not in slow start phase,set the congestion window size //to the product of packet arrival rate and(rtt +SYN) @@ -148,51 +147,51 @@ } } - //no rate increase in slow start + //no rate increase during slow start if(slowStartPhase)return; - + + //no rate increase "immediately" after a NAK if(loss){ loss=false; return; } - - //4.compute the number of sent packets to be increase in the next SYN period - //and update the send intervall - numOfIncreasingPacket=computeNumOfIncreasingPacket(); - - //4.update the send period : + + //4. compute the increase in sent packets for the next SYN period + double numOfIncreasingPacket=computeNumOfIncreasingPacket(); + + //5. update the send period double factor=Util.getSYNTimeD()/(packetSendingPeriod*numOfIncreasingPacket+Util.getSYNTimeD()); packetSendingPeriod=factor*packetSendingPeriod; //packetSendingPeriod=0.995*packetSendingPeriod; //System.out.println("dec snd factor "+factor+" to "+packetSendingPeriod); - + statistics.setSendPeriod(packetSendingPeriod); } private final long PS=UDPEndPoint.DATAGRAM_SIZE; private final double BetaDivPS=0.0000015/PS; - + //see spec page 16 private double computeNumOfIncreasingPacket (){ - //link capacity and sending speed, in packets per second - double B=estimatedLinkCapacity; - double C=1000000.0/packetSendingPeriod; - - if(B<=C)return 1.0/UDPEndPoint.DATAGRAM_SIZE; - - double exp=Math.ceil(Math.log10((B-C)*PS*8)); - double power10 = Math.pow( 10.0, exp)* BetaDivPS; - double inc = Math.max(power10, 1/PS); - return inc; + //difference in link capacity and sending speed, in packets per second + double remaining=estimatedLinkCapacity-1000000.0/packetSendingPeriod; + + if(remaining<=0){ + return 1.0/UDPEndPoint.DATAGRAM_SIZE; + } + else{ + double exp=Math.ceil(Math.log10(remaining*PS*8)); + double power10 = Math.pow( 10.0, exp)* BetaDivPS; + return Math.max(power10, 1/PS); + } } - + /* (non-Javadoc) * @see udt.CongestionControl#onNAK(java.util.List) */ public void onNAK(List<Integer>lossInfo){ loss=true; - long firstBiggestlossSeqNo=lossInfo.get(lossInfo.size()-1); - + long firstBiggestlossSeqNo=lossInfo.get(0); nACKCount++; /*1) If it is in slow start phase, set inter-packet interval to 1/recvrate. Slow start ends. Stop. */ @@ -206,12 +205,10 @@ slowStartPhase = false; return; } - + long currentMaxSequenceNumber=session.getSocket().getSender().getCurrentSequenceNumber(); - // 2)If this NAK starts a new congestion epoch if(firstBiggestlossSeqNo>lastDecreaseSeqNo){ - // -increase inter-packet interval packetSendingPeriod = Math.ceil(packetSendingPeriod*1.125); // -Update AvgNAKNum(the average number of NAKs per congestion) @@ -224,20 +221,19 @@ // -Update LastDecSeq lastDecreaseSeqNo = currentMaxSequenceNumber; // -Stop. - statistics.setSendPeriod(packetSendingPeriod); } - //* 3) If DecCount <= 5, and NAKCount == DecCount * DecRandom: - if(decCount<=5 && nACKCount==decCount*decreaseRandom){ + else if(decCount<=5 && nACKCount==decCount*decreaseRandom){ // a. Update SND period: SND = SND * 1.125; packetSendingPeriod = Math.ceil(packetSendingPeriod*1.125); // b. Increase DecCount by 1; decCount++; // c. Record the current largest sent sequence number (LastDecSeq). lastDecreaseSeqNo= currentMaxSequenceNumber; - statistics.setSendPeriod(packetSendingPeriod); - return; } + + statistics.setSendPeriod(packetSendingPeriod); + return; } /* (non-Javadoc) Modified: udt-java/trunk/src/main/java/udt/UDTSender.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSender.java 2010-04-21 15:45:00 UTC (rev 21) +++ udt-java/trunk/src/main/java/udt/UDTSender.java 2010-04-21 20:36:36 UTC (rev 22) @@ -253,10 +253,10 @@ statistics.incNumberOfNAKReceived(); statistics.storeParameters(); - //if(logger.isLoggable(Level.FINER)){ - System.out.println("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " + if(logger.isLoggable(Level.FINER)){ + logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " +"set send period to "+session.getCongestionControl().getSendInterval()); - //} + } return; } @@ -315,12 +315,9 @@ if(unAcknowledged<session.getCongestionControl().getCongestionWindowSize() && unAcknowledged<session.getFlowWindowSize()){ -// if(lastSentTime>0 && Util.getCurrentTime()-lastSentTime<snd){ -// statistics.incNumberOfCCSlowDownEvents(); -// return; -// } + if(sendQueue.size()==0){ - Thread.yield(); + //Thread.yield(); return; } DataPacket dp=sendQueue.poll(20,TimeUnit.MILLISECONDS); @@ -340,10 +337,12 @@ //wait double snd=session.getCongestionControl().getSendInterval(); long passed=Util.getCurrentTime()-iterationStart; + int x=0; while(snd-passed>0){ - //busy wait, but we cannot wait with microsecond precision + if(x++==0)statistics.incNumberOfCCSlowDownEvents(); + //we cannot wait with microsecond precision if(snd-passed>750)Thread.sleep(1); - statistics.incNumberOfCCSlowDownEvents(); + else Thread.yield(); passed=Util.getCurrentTime()-iterationStart; } @@ -394,8 +393,9 @@ return largestSentSequenceNumber>=sequenceNumber; } + boolean haveLostPackets(){ - return senderLossList.isEmpty(); + return !senderLossList.isEmpty(); } /** Modified: udt-java/trunk/src/main/java/udt/receiver/PacketPairWindow.java =================================================================== --- udt-java/trunk/src/main/java/udt/receiver/PacketPairWindow.java 2010-04-21 15:45:00 UTC (rev 21) +++ udt-java/trunk/src/main/java/udt/receiver/PacketPairWindow.java 2010-04-21 20:36:36 UTC (rev 22) @@ -79,7 +79,6 @@ } } double res=total/count; - //System.out.println("median: "+median+" filtered "+res); return res; } Modified: udt-java/trunk/src/main/java/udt/sender/SenderLossList.java =================================================================== --- udt-java/trunk/src/main/java/udt/sender/SenderLossList.java 2010-04-21 15:45:00 UTC (rev 21) +++ udt-java/trunk/src/main/java/udt/sender/SenderLossList.java 2010-04-21 20:36:36 UTC (rev 22) @@ -31,7 +31,6 @@ *********************************************************************************/ package udt.sender; -import java.util.Iterator; import java.util.concurrent.PriorityBlockingQueue; /** Modified: udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-04-21 15:45:00 UTC (rev 21) +++ udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-04-21 20:36:36 UTC (rev 22) @@ -20,7 +20,7 @@ boolean running=false; //how many - int num_packets=200; + int num_packets=100; //how large is a single packet int size=1*1024*1024; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2010-04-25 20:32:29
|
Revision: 24 http://udt-java.svn.sourceforge.net/udt-java/?rev=24&view=rev Author: bschuller Date: 2010-04-25 20:32:22 +0000 (Sun, 25 Apr 2010) Log Message: ----------- simpler InputStream; fix wrong value for EXP interval Modified Paths: -------------- udt-java/trunk/src/main/java/udt/UDTInputStream.java udt-java/trunk/src/main/java/udt/UDTReceiver.java udt-java/trunk/src/main/java/udt/UDTSender.java udt-java/trunk/src/main/java/udt/sender/SenderLossList.java udt-java/trunk/src/main/java/udt/sender/SenderLossListEntry.java udt-java/trunk/src/main/java/udt/util/UDTStatistics.java udt-java/trunk/src/test/java/udt/TestUDTInputStream.java udt-java/trunk/src/test/java/udt/UDTTestBase.java udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java Added Paths: ----------- udt-java/trunk/src/main/java/udt/util/MeanValue.java Modified: udt-java/trunk/src/main/java/udt/UDTInputStream.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTInputStream.java 2010-04-22 10:06:54 UTC (rev 23) +++ udt-java/trunk/src/main/java/udt/UDTInputStream.java 2010-04-25 20:32:22 UTC (rev 24) @@ -34,7 +34,6 @@ import java.io.IOException; import java.io.InputStream; -import java.nio.ByteBuffer; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -66,13 +65,10 @@ //see the noMoreData() method private final AtomicBoolean expectMoreData=new AtomicBoolean(true); - - private final ByteBuffer buffer; - private volatile boolean closed=false; - + private volatile boolean blocking=true; - + /** * create a new {@link UDTInputStream} connected to the given socket * @param socket - the {@link UDTSocket} @@ -83,8 +79,6 @@ this.socket=socket; this.statistics=statistics; appData=new FlowWindow<AppData>(getFlowWindowSize()); - buffer=ByteBuffer.allocate(65536); - buffer.flip(); } private int getFlowWindowSize(){ @@ -107,7 +101,7 @@ int b=0; while(b==0) b=read(single); - + if(b>0){ return single[0]; } @@ -115,24 +109,39 @@ return b; } } - + private AppData currentChunk=null; + //offset into currentChunk int offset=0; + @Override public int read(byte[]target)throws IOException{ try{ - //empty the buffer first - int read=readFromBuffer(target, 0); - //if no more space left in target, exit now - if(read==target.length){ - return target.length; + int read=0; + updateCurrentChunk(); + while(currentChunk!=null){ + byte[]data=currentChunk.data; + int length=Math.min(target.length-read,data.length-offset); + System.arraycopy(data, offset, target, read, length); + read+=length; + offset+=length; + //check if chunk has been fully read + if(offset>=data.length){ + currentChunk=null; + offset=0; + } + + //if no more space left in target, exit now + if(read==target.length){ + return read; + } + + updateCurrentChunk(); } - //otherwise try to fill up the buffer - fillBuffer(); - read+=readFromBuffer(target, read); + if(read>0)return read; if(closed)return -1; - if(expectMoreData.get() || buffer.remaining()>0 || !appData.isEmpty())return 0; + if(expectMoreData.get() || !appData.isEmpty())return 0; //no more data return -1; @@ -143,20 +152,18 @@ } } - @Override - public int available()throws IOException{ - return buffer.remaining(); - } - /** - * write as much data into the ByteBuffer as possible<br/> + * Reads the next valid chunk of application data from the queue<br/> + * * In blocking mode,this method will block until data is available or the socket is closed, - * otherwise wait for at most 10 milliseconds. - * @returns <code>true</code> if data available + * otherwise it will wait for at most 10 milliseconds. + * * @throws InterruptedException */ - private boolean fillBuffer()throws IOException{ - if(currentChunk==null){ + private void updateCurrentChunk()throws IOException{ + if(currentChunk!=null)return; + + while(true){ try{ if(blocking){ currentChunk=appData.poll(1, TimeUnit.MILLISECONDS); @@ -170,51 +177,29 @@ ex.initCause(ie); throw ex; } - } - if(currentChunk!=null){ - //check if the data is in-order - if(currentChunk.sequenceNumber==highestSequenceNumber+1){ - highestSequenceNumber++; - statistics.updateReadDataMD5(currentChunk.data); + if(currentChunk!=null){ + //check if the data is in-order + if(currentChunk.sequenceNumber==highestSequenceNumber+1){ + highestSequenceNumber++; + statistics.updateReadDataMD5(currentChunk.data); + return; + } + else if(currentChunk.sequenceNumber<=highestSequenceNumber){ + //duplicate, drop it + currentChunk=null; + statistics.incNumberOfDuplicateDataPackets(); + } + else{ + //out of order data, put back into queue and exit + appData.offer(currentChunk); + currentChunk=null; + return; + } } - else if(currentChunk.sequenceNumber<=highestSequenceNumber){ - //duplicate, drop it - currentChunk=null; - statistics.incNumberOfDuplicateDataPackets(); - return false; - } - else{ - //out of order data, put back into queue - appData.offer(currentChunk); - currentChunk=null; - return false; - } - - //fill data into the buffer - buffer.compact(); - int len=Math.min(buffer.remaining(),currentChunk.data.length-offset); - buffer.put(currentChunk.data,offset,len); - buffer.flip(); - offset+=len; - //check if the chunk has been fully read - if(offset>=currentChunk.data.length){ - currentChunk=null; - offset=0; - } + else return; } - return true; } - //read data from the internal buffer into target at the specified offset - private int readFromBuffer(byte[] target, int offset){ - int available=buffer.remaining(); - int canRead=Math.min(available, target.length-offset); - if(canRead>0){ - buffer.get(target, offset, canRead); - } - return canRead; - } - /** * new application data * @param data @@ -231,7 +216,7 @@ closed=true; noMoreData(); } - + public UDTSocket getSocket(){ return socket; } @@ -243,7 +228,7 @@ public void setBlocking(boolean block){ this.blocking=block; } - + /** * notify the input stream that there is no more data * @throws IOException @@ -277,7 +262,7 @@ final int prime = 31; int result = 1; result = prime * result - + (int) (sequenceNumber ^ (sequenceNumber >>> 32)); + + (int) (sequenceNumber ^ (sequenceNumber >>> 32)); return result; } @@ -294,8 +279,8 @@ return false; return true; } - - + + } } Modified: udt-java/trunk/src/main/java/udt/UDTReceiver.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-04-22 10:06:54 UTC (rev 23) +++ udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-04-25 20:32:22 UTC (rev 24) @@ -125,7 +125,7 @@ private long nextEXP; //microseconds to next EXP event - private long EXP_INTERVAL=Util.getSYNTime(); + private long EXP_INTERVAL=100*Util.getSYNTime(); //instant when the session was created (for expiry checking) private final long sessionUpSince; @@ -348,7 +348,7 @@ public static int dropRate=0; //number of received data packets private int n=0; - + protected void onDataPacketReceived(DataPacket dp)throws IOException{ long currentSequenceNumber = dp.getPacketSequenceNumber(); //check whether to drop this packet @@ -367,9 +367,11 @@ long interval=currentDataPacketArrivalTime -lastDataPacketArrivalTime; packetPairWindow.add(interval); } + //(5).record the packet arrival time in the PKT History Window. packetHistoryWindow.add(currentDataPacketArrivalTime); + //store current time lastDataPacketArrivalTime=currentDataPacketArrivalTime; Modified: udt-java/trunk/src/main/java/udt/UDTSender.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSender.java 2010-04-22 10:06:54 UTC (rev 23) +++ udt-java/trunk/src/main/java/udt/UDTSender.java 2010-04-25 20:32:22 UTC (rev 24) @@ -286,14 +286,12 @@ SenderLossListEntry entry=senderLossList.getFirstEntry(); if (entry!=null) { long seqNumber = entry.getSequenceNumber(); - //TODO //if the current seqNumber is 16n,check the timeOut in the //loss list and send a message drop request. //if((seqNumber%16)==0){ //sendLossList.checkTimeOut(timeToLive); //} - try { //retransmit the packet with the first entry in the list //as sequence number and remove it from the list @@ -301,8 +299,7 @@ if(pktToRetransmit!=null){ endpoint.doSend(pktToRetransmit); statistics.incNumberOfRetransmittedDataPackets(); - } - senderLossList.remove(seqNumber); + } }catch (Exception e) { logger.log(Level.WARNING,"",e); } @@ -352,6 +349,7 @@ * for processing EXP event (see spec. p 13) */ protected void putUnacknowledgedPacketsIntoLossList(){ + synchronized (sendLock) { for(Long l: sendBuffer.keySet()){ senderLossList.insert(new SenderLossListEntry(l)); Modified: udt-java/trunk/src/main/java/udt/sender/SenderLossList.java =================================================================== --- udt-java/trunk/src/main/java/udt/sender/SenderLossList.java 2010-04-22 10:06:54 UTC (rev 23) +++ udt-java/trunk/src/main/java/udt/sender/SenderLossList.java 2010-04-25 20:32:22 UTC (rev 24) @@ -58,7 +58,8 @@ } /** - * gets the loss list entry with the lowest sequence number + * retrieves the loss list entry with the lowest sequence number and removes + * it from the loss list */ public SenderLossListEntry getFirstEntry(){ return backingList.poll(); @@ -68,4 +69,7 @@ return backingList.isEmpty(); } + public long size(){ + return backingList.size(); + } } Modified: udt-java/trunk/src/main/java/udt/sender/SenderLossListEntry.java =================================================================== --- udt-java/trunk/src/main/java/udt/sender/SenderLossListEntry.java 2010-04-22 10:06:54 UTC (rev 23) +++ udt-java/trunk/src/main/java/udt/sender/SenderLossListEntry.java 2010-04-25 20:32:22 UTC (rev 24) @@ -94,4 +94,7 @@ return true; } + public String toString(){ + return "lossListEntry-"+sequenceNumber; + } } Added: udt-java/trunk/src/main/java/udt/util/MeanValue.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/MeanValue.java (rev 0) +++ udt-java/trunk/src/main/java/udt/util/MeanValue.java 2010-04-25 20:32:22 UTC (rev 24) @@ -0,0 +1,38 @@ +package udt.util; + +import java.text.NumberFormat; + +/** + * holds a floating mean value + */ +public class MeanValue { + + private double mean=0; + + private int n=0; + + private final NumberFormat format; + + + public MeanValue(){ + format=NumberFormat.getNumberInstance(); + format.setMaximumFractionDigits(2); + } + public void addValue(double value){ + mean=(mean*n+value)/(n+1); + n++; + } + + public double getMean(){ + return mean; + } + + public String getFormattedMean(){ + return format.format(mean); + } + + public void clear(){ + mean=0; + n=0; + } +} Property changes on: udt-java/trunk/src/main/java/udt/util/MeanValue.java ___________________________________________________________________ Added: svn:mime-type + text/plain Modified: udt-java/trunk/src/main/java/udt/util/UDTStatistics.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/UDTStatistics.java 2010-04-22 10:06:54 UTC (rev 23) +++ udt-java/trunk/src/main/java/udt/util/UDTStatistics.java 2010-04-25 20:32:22 UTC (rev 24) @@ -150,6 +150,10 @@ this.sendPeriod=sendPeriod; } + public double getSendPeriod(){ + return sendPeriod; + } + public void updateReadDataMD5(byte[]data){ digest.update(data); } Modified: udt-java/trunk/src/test/java/udt/TestUDTInputStream.java =================================================================== --- udt-java/trunk/src/test/java/udt/TestUDTInputStream.java 2010-04-22 10:06:54 UTC (rev 23) +++ udt-java/trunk/src/test/java/udt/TestUDTInputStream.java 2010-04-25 20:32:22 UTC (rev 24) @@ -13,30 +13,46 @@ byte[] data2="a test".getBytes(); byte[] data3=" string".getBytes(); String digest=computeMD5(data1,data2,data3); - is.haveNewData(0, data1); - is.haveNewData(1, data2); - is.haveNewData(2, data3); + is.haveNewData(1, data1); + is.haveNewData(2, data2); + is.haveNewData(3, data3); is.noMoreData(); is.setBlocking(false); readAll(is,8); assertEquals(digest,stat.getDigest()); } + public void test2()throws Exception{ + UDTStatistics stat=new UDTStatistics("test"); + UDTInputStream is=new UDTInputStream(null, stat); + byte[] data1=getRandomData(65537); + byte[] data2=getRandomData(1234); + byte[] data3=getRandomData(3*1024*1024); + String digest=computeMD5(data1,data2,data3); + is.setBlocking(false); + is.haveNewData(1, data1); + is.haveNewData(2, data2); + is.haveNewData(3, data3); + is.noMoreData(); + readAll(is,5*1024*1024); + assertEquals(digest,stat.getDigest()); + } + public void testInOrder()throws Exception{ UDTStatistics stat=new UDTStatistics("test"); UDTInputStream is=new UDTInputStream(null, stat); is.setBlocking(false); - byte[]data=getRandomData(10*1024); + byte[]data=getRandomData(10*1024*1024); byte[][]blocks=makeChunks(10,data); String digest=computeMD5(blocks); for(int i=0;i<10;i++){ - is.haveNewData(i, blocks[i]); + is.haveNewData(i+1, blocks[i]); } is.noMoreData(); - readAll(is,512); + readAll(is,1024*999); assertEquals(digest,stat.getDigest()); } @@ -52,7 +68,7 @@ byte[]order=new byte[]{9,7,5,3,1,2,0,4,6,8}; for(int i : order){ - is.haveNewData(i, blocks[i]); + is.haveNewData(i+1, blocks[i]); } readAll(is,512,true); @@ -70,7 +86,7 @@ is.noMoreData(); if(c==-1)break; else{ - d.update(buf,0,c); + if(c>0)d.update(buf,0,c); } } return UDTStatistics.hexString(d); Modified: udt-java/trunk/src/test/java/udt/UDTTestBase.java =================================================================== --- udt-java/trunk/src/test/java/udt/UDTTestBase.java 2010-04-22 10:06:54 UTC (rev 23) +++ udt-java/trunk/src/test/java/udt/UDTTestBase.java 2010-04-25 20:32:22 UTC (rev 24) @@ -5,6 +5,8 @@ import java.security.MessageDigest; import java.util.Random; +import udt.util.UDTStatistics; + import junit.framework.TestCase; /** @@ -58,14 +60,7 @@ } public static String hexString(MessageDigest digest){ - byte[] messageDigest = digest.digest(); - StringBuilder hexString = new StringBuilder(); - for (int i=0;i<messageDigest.length;i++) { - String hex = Integer.toHexString(0xFF & messageDigest[i]); - if(hex.length()==1)hexString.append('0'); - hexString.append(hex); - } - return hexString.toString(); + return UDTStatistics.hexString(digest); } Modified: udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-04-22 10:06:54 UTC (rev 23) +++ udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-04-25 20:32:22 UTC (rev 24) @@ -21,7 +21,7 @@ boolean running=false; //how many - int num_packets=200; + int num_packets=100; //how large is a single packet int size=1*1024*1024; @@ -64,7 +64,12 @@ client.sendBlocking(data); digest.update(data); double took=System.currentTimeMillis()-block; - System.out.println("Sent block <"+i+"> in "+took+" ms, rate: "+format.format(size/(1024*took))+ " Mbytes/sec"); + double arrival=client.getStatistics().getPacketArrivalRate(); + double snd=client.getStatistics().getSendPeriod(); + System.out.println("Sent block <"+i+"> in "+took+" ms, " + +" pktArr: "+arrival + + " snd: "+format.format(snd) + +" rate: "+format.format(size/(1024*took))+ " MB/sec"); } end=System.currentTimeMillis(); client.shutdown(); @@ -74,7 +79,7 @@ while(serverRunning)Thread.sleep(100); System.out.println("Done. Sending "+N/1024/1024+" Mbytes took "+(end-start)+" ms"); - double mbytes=N/(end-start)/1024; + double mbytes=N/(end-start)/1024.0; double mbit=8*mbytes; System.out.println("Rate: "+format.format(mbytes)+" Mbytes/sec "+format.format(mbit)+" Mbit/sec"); System.out.println("Server received: "+total); @@ -117,7 +122,6 @@ else{ md5.update(buf, 0, c); total+=c; - Thread.yield(); } } System.out.println("Server thread exiting, last received bytes: "+c); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2010-04-25 21:29:46
|
Revision: 25 http://udt-java.svn.sourceforge.net/udt-java/?rev=25&view=rev Author: bschuller Date: 2010-04-25 21:29:40 +0000 (Sun, 25 Apr 2010) Log Message: ----------- Modified Paths: -------------- udt-java/trunk/src/main/java/udt/UDTInputStream.java udt-java/trunk/src/main/java/udt/util/ReceiveFile.java udt-java/trunk/src/main/java/udt/util/SendFile.java udt-java/trunk/src/test/java/udt/TestSendFileReceiveFile.java Modified: udt-java/trunk/src/main/java/udt/UDTInputStream.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTInputStream.java 2010-04-25 20:32:22 UTC (rev 24) +++ udt-java/trunk/src/main/java/udt/UDTInputStream.java 2010-04-25 21:29:40 UTC (rev 25) @@ -118,7 +118,7 @@ public int read(byte[]target)throws IOException{ try{ int read=0; - updateCurrentChunk(); + updateCurrentChunk(false); while(currentChunk!=null){ byte[]data=currentChunk.data; int length=Math.min(target.length-read,data.length-offset); @@ -136,7 +136,7 @@ return read; } - updateCurrentChunk(); + updateCurrentChunk(blocking && read==0); } if(read>0)return read; @@ -160,12 +160,12 @@ * * @throws InterruptedException */ - private void updateCurrentChunk()throws IOException{ + private void updateCurrentChunk(boolean block)throws IOException{ if(currentChunk!=null)return; while(true){ try{ - if(blocking){ + if(block){ currentChunk=appData.poll(1, TimeUnit.MILLISECONDS); while (!closed && currentChunk==null){ currentChunk=appData.poll(1000, TimeUnit.MILLISECONDS); Modified: udt-java/trunk/src/main/java/udt/util/ReceiveFile.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/ReceiveFile.java 2010-04-25 20:32:22 UTC (rev 24) +++ udt-java/trunk/src/main/java/udt/util/ReceiveFile.java 2010-04-25 21:29:40 UTC (rev 25) @@ -76,11 +76,13 @@ byte[]readBuf=new byte[1024]; ByteBuffer bb=ByteBuffer.wrap(readBuf); - + System.out.println("[ReceiveFile] Requesting file "+remoteFile); //send name file info byte[]fName=remoteFile.getBytes(); - bb.putInt(fName.length); + bb.putInt(fName.length+1); + bb.put(fName); + bb.put((byte)0); out.write(readBuf, 0, bb.position()); Modified: udt-java/trunk/src/main/java/udt/util/SendFile.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/SendFile.java 2010-04-25 20:32:22 UTC (rev 24) +++ udt-java/trunk/src/main/java/udt/util/SendFile.java 2010-04-25 21:29:40 UTC (rev 25) @@ -132,8 +132,8 @@ byte[]readBuf=new byte[32768]; ByteBuffer bb=ByteBuffer.wrap(readBuf); - //read name file info - in.read(readBuf); + //read file name info + while(in.read(readBuf)==0)Thread.sleep(100); //how many bytes to read for the file name int length=bb.getInt(); Modified: udt-java/trunk/src/test/java/udt/TestSendFileReceiveFile.java =================================================================== --- udt-java/trunk/src/test/java/udt/TestSendFileReceiveFile.java 2010-04-25 20:32:22 UTC (rev 24) +++ udt-java/trunk/src/test/java/udt/TestSendFileReceiveFile.java 2010-04-25 21:29:40 UTC (rev 25) @@ -18,7 +18,6 @@ }while(!serverStarted); File f=new File("src/test/java/datafile"); - f=new File("/tmp/200MB"); File tmp=File.createTempFile("udtest-", null); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2010-04-29 15:26:45
|
Revision: 30 http://udt-java.svn.sourceforge.net/udt-java/?rev=30&view=rev Author: bschuller Date: 2010-04-29 15:26:39 +0000 (Thu, 29 Apr 2010) Log Message: ----------- minor performance improvements; add metric code for easier measuring of performance Modified Paths: -------------- udt-java/trunk/src/main/java/udt/ClientSession.java udt-java/trunk/src/main/java/udt/ServerSession.java udt-java/trunk/src/main/java/udt/UDPEndPoint.java udt-java/trunk/src/main/java/udt/UDTCongestionControl.java udt-java/trunk/src/main/java/udt/UDTInputStream.java udt-java/trunk/src/main/java/udt/UDTPacket.java udt-java/trunk/src/main/java/udt/UDTReceiver.java udt-java/trunk/src/main/java/udt/UDTSender.java udt-java/trunk/src/main/java/udt/UDTSession.java udt-java/trunk/src/main/java/udt/packets/Acknowledgement.java udt-java/trunk/src/main/java/udt/packets/Acknowledgment2.java udt-java/trunk/src/main/java/udt/packets/ConnectionHandshake.java udt-java/trunk/src/main/java/udt/packets/ControlPacket.java udt-java/trunk/src/main/java/udt/packets/DataPacket.java udt-java/trunk/src/main/java/udt/packets/KeepAlive.java udt-java/trunk/src/main/java/udt/packets/MessageDropRequest.java udt-java/trunk/src/main/java/udt/packets/NegativeAcknowledgement.java udt-java/trunk/src/main/java/udt/packets/PacketFactory.java udt-java/trunk/src/main/java/udt/packets/Shutdown.java udt-java/trunk/src/main/java/udt/packets/UserDefined.java udt-java/trunk/src/main/java/udt/util/MeanValue.java udt-java/trunk/src/main/java/udt/util/ReceiveFile.java udt-java/trunk/src/main/java/udt/util/UDTStatistics.java udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java udt-java/trunk/src/test/java/udt/performance/UDPTest.java Modified: udt-java/trunk/src/main/java/udt/ClientSession.java =================================================================== --- udt-java/trunk/src/main/java/udt/ClientSession.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/ClientSession.java 2010-04-29 15:26:39 UTC (rev 30) @@ -80,6 +80,7 @@ logger.info("Connected, "+n+" handshake packets sent"); } + @Override public void received(UDTPacket packet, Destination peer) { @@ -99,6 +100,7 @@ return; } if(getState() == ready) { + if(packet instanceof Shutdown){ setState(shutdown); active=false; Modified: udt-java/trunk/src/main/java/udt/ServerSession.java =================================================================== --- udt-java/trunk/src/main/java/udt/ServerSession.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/ServerSession.java 2010-04-29 15:26:39 UTC (rev 30) @@ -43,6 +43,7 @@ import udt.packets.Destination; import udt.packets.KeepAlive; import udt.packets.Shutdown; +import udt.util.MeanValue; /** * server side session in client-server mode @@ -67,7 +68,6 @@ @Override public void received(UDTPacket packet, Destination peer){ lastPacket=packet; - if (getState()<=ready && packet instanceof ConnectionHandshake) { logger.info("Received ConnectionHandshake from "+peer); ConnectionHandshake connectionHandshake=(ConnectionHandshake)packet; Modified: udt-java/trunk/src/main/java/udt/UDPEndPoint.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDPEndPoint.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/UDPEndPoint.java 2010-04-29 15:26:39 UTC (rev 30) @@ -83,7 +83,7 @@ private volatile boolean stopped=false; public static final int DATAGRAM_SIZE=1500; - + /** * bind to any local port on the given host address * @param localAddress @@ -113,9 +113,9 @@ clientSessions=new ConcurrentHashMap<Destination, UDTSession>(); sessionHandoff=new SynchronousQueue<UDTSession>(); //set a time out to avoid blocking in doReceive() - dgSocket.setSoTimeout(1000); + dgSocket.setSoTimeout(100000); //buffer size - dgSocket.setReceiveBufferSize(512*1024); + dgSocket.setReceiveBufferSize(128*1024); } /** @@ -151,9 +151,7 @@ Runnable receive=new Runnable(){ public void run(){ try{ - while(!stopped){ - doReceive(); - } + doReceive(); }catch(Exception ex){ ex.printStackTrace(); } @@ -240,65 +238,68 @@ */ private long lastDestID=-1; private UDTSession lastSession; - MeanValue v=new MeanValue(true,64); + + MeanValue v=new MeanValue("",false); + protected void doReceive()throws IOException{ - try{ + while(!stopped){ try{ - //will block until a packet is received or timeout has expired - dgSocket.receive(dp); - Destination peer=new Destination(dp.getAddress(), dp.getPort()); - int l=dp.getLength(); - UDTPacket packet=PacketFactory.createPacket(dp.getData(),l); - lastPacket=packet; + try{ + //will block until a packet is received or timeout has expired + dgSocket.receive(dp); + + Destination peer=new Destination(dp.getAddress(), dp.getPort()); + int l=dp.getLength(); + UDTPacket packet=PacketFactory.createPacket(dp.getData(),l); + lastPacket=packet; - //handle connection handshake - if(packet.isConnectionHandshake()){ - UDTSession session=clientSessions.get(peer); - - if(session==null){ - session=new ServerSession(dp,this); - addSession(session.getSocketID(),session); - //TODO need to check peer to avoid duplicate server session - if(serverSocketMode){ - logger.fine("Pooling new request."); - sessionHandoff.put(session); - logger.fine("Request taken for processing."); + //handle connection handshake + if(packet.isConnectionHandshake()){ + UDTSession session=clientSessions.get(peer); + if(session==null){ + session=new ServerSession(dp,this); + addSession(session.getSocketID(),session); + //TODO need to check peer to avoid duplicate server session + if(serverSocketMode){ + logger.fine("Pooling new request."); + sessionHandoff.put(session); + logger.fine("Request taken for processing."); + } } + peer.setSocketID(((ConnectionHandshake)packet).getSocketID()); + session.received(packet,peer); } - peer.setSocketID(((ConnectionHandshake)packet).getSocketID()); - session.received(packet,peer); - } - - else{ - //dispatch to existing session - long dest=packet.getDestinationID(); - UDTSession session; - if(dest==lastDestID){ - session=lastSession; - } else{ - session=sessions.get(dest); - lastSession=session; - lastDestID=dest; + //dispatch to existing session + long dest=packet.getDestinationID(); + UDTSession session; + if(dest==lastDestID){ + session=lastSession; + } + else{ + session=sessions.get(dest); + lastSession=session; + lastDestID=dest; + } + if(session==null){ + logger.warning("Unknown session <"+packet.getDestinationID()+"> requested from <"+peer+"> packet type "+packet.getClass().getName()); + } + else{ + session.received(packet,peer); + } } - if(session==null){ - logger.warning("Unknown session <"+packet.getDestinationID()+"> requested from <"+peer+"> packet type "+packet.getClass().getName()); - } - else{ - session.received(packet,peer); - } + }catch(SocketException ex){ + logger.log(Level.INFO, "SocketException: "+ex.getMessage()); + }catch(SocketTimeoutException ste){ + //can safely ignore... we will retry until the endpoint is stopped } - }catch(SocketException ex){ - logger.log(Level.INFO, "SocketException: "+ex.getMessage()); - }catch(SocketTimeoutException ste){ - //can safely ignore... we will retry until the endpoint is stopped + + }catch(Exception ex){ + logger.log(Level.WARNING, "Got: "+ex.getMessage(),ex); } - - }catch(Exception ex){ - logger.log(Level.WARNING, "Got: "+ex.getMessage(),ex); } } - + protected void doSend(UDTPacket packet)throws IOException{ byte[]data=packet.getEncoded(); DatagramPacket dgp = packet.getSession().getDatagram(); Modified: udt-java/trunk/src/main/java/udt/UDTCongestionControl.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTCongestionControl.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/UDTCongestionControl.java 2010-04-29 15:26:39 UTC (rev 30) @@ -30,7 +30,7 @@ private long estimatedLinkCapacity=0; // Packet sending period = packet send interval, in microseconds - private double packetSendingPeriod=0; + private double packetSendingPeriod=1; // Congestion window size, in packets private long congestionWindowSize=16; @@ -229,9 +229,6 @@ lastDecreaseSeqNo= currentMaxSequenceNumber; } - //enforce upper limit on send period... - //packetSendingPeriod=Math.min(packetSendingPeriod, 2*roundTripTime); - statistics.setSendPeriod(packetSendingPeriod); return; } Modified: udt-java/trunk/src/main/java/udt/UDTInputStream.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTInputStream.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/UDTInputStream.java 2010-04-29 15:26:39 UTC (rev 30) @@ -78,7 +78,7 @@ public UDTInputStream(UDTSocket socket, UDTStatistics statistics)throws IOException{ this.socket=socket; this.statistics=statistics; - appData=new PriorityBlockingQueue<AppData>(128); + appData=new PriorityBlockingQueue<AppData>(socket.getSession().getFlowWindowSize()); } /** @@ -178,7 +178,7 @@ //check if the data is in-order if(currentChunk.sequenceNumber==highestSequenceNumber+1){ highestSequenceNumber++; - statistics.updateReadDataMD5(currentChunk.data); + //statistics.updateReadDataMD5(currentChunk.data); return; } else if(currentChunk.sequenceNumber<=highestSequenceNumber){ Modified: udt-java/trunk/src/main/java/udt/UDTPacket.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTPacket.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/UDTPacket.java 2010-04-29 15:26:39 UTC (rev 30) @@ -48,6 +48,8 @@ public boolean isControlPacket(); + public int getControlPacketType(); + /** * header * @return Modified: udt-java/trunk/src/main/java/udt/UDTReceiver.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-04-29 15:26:39 UTC (rev 30) @@ -53,6 +53,7 @@ import udt.receiver.PacketPairWindow; import udt.receiver.ReceiverLossList; import udt.receiver.ReceiverLossListEntry; +import udt.util.MeanValue; import udt.util.UDTStatistics; import udt.util.UDTThreadFactory; import udt.util.Util; @@ -168,9 +169,26 @@ //incoming packets are ordered by sequence number, with control packets having //preference over data packets handoffQueue=new PriorityBlockingQueue<UDTPacket>(session.getFlowWindowSize()); + initMetrics(); start(); } + + private MeanValue dgReceiveInterval; + private MeanValue dataPacketInterval; + private MeanValue processTime; + private MeanValue dataProcessTime; + private void initMetrics(){ + dgReceiveInterval=new MeanValue("UDT receive interval"); + statistics.addMetric(dgReceiveInterval); + dataPacketInterval=new MeanValue("Data packet interval"); + statistics.addMetric(dataPacketInterval); + processTime=new MeanValue("UDT packet process time"); + statistics.addMetric(processTime); + dataProcessTime=new MeanValue("Data packet process time"); + statistics.addMetric(dataProcessTime); + } + //starts the sender algorithm private void start(){ Runnable r=new Runnable(){ @@ -197,7 +215,9 @@ * packets are written by the endpoint */ protected void receive(UDTPacket p)throws IOException{ + dgReceiveInterval.end(); handoffQueue.offer(p); + dgReceiveInterval.begin(); } /** @@ -222,7 +242,6 @@ nextEXP=currentTime+EXP_INTERVAL; processEXPEvent(); } - //perform time-bounded UDP receive UDTPacket packet=handoffQueue.poll(Util.getSYNTime(), TimeUnit.MICROSECONDS); if(packet!=null){ @@ -233,7 +252,7 @@ boolean needEXPReset=false; if(packet.isControlPacket()){ ControlPacket cp=(ControlPacket)packet; - int cpType=cp.getControlPaketType(); + int cpType=cp.getControlPacketType(); if(cpType==ControlPacketType.ACK.ordinal() || cpType==ControlPacketType.NAK.ordinal()){ needEXPReset=true; } @@ -241,7 +260,9 @@ if(needEXPReset){ nextEXP=Util.getCurrentTime()+EXP_INTERVAL; } + processTime.begin(); processUDTPacket(packet); + processTime.end(); } Thread.yield(); @@ -324,12 +345,16 @@ protected void processUDTPacket(UDTPacket p)throws IOException{ //(3).Check the packet type and process it according to this. - if(p instanceof DataPacket){ + if(!p.isControlPacket()){ DataPacket dp=(DataPacket)p; + dataPacketInterval.end(); + dataProcessTime.begin(); onDataPacketReceived(dp); + dataProcessTime.end(); + dataPacketInterval.begin(); } - else if (p instanceof Acknowledgment2){ + else if (p.getControlPacketType()==ControlPacketType.ACK2.ordinal()){ Acknowledgment2 ack2=(Acknowledgment2)p; onAck2PacketReceived(ack2); } Modified: udt-java/trunk/src/main/java/udt/UDTSender.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSender.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/UDTSender.java 2010-04-29 15:26:39 UTC (rev 30) @@ -51,6 +51,7 @@ import udt.packets.NegativeAcknowledgement; import udt.sender.SenderLossList; import udt.sender.SenderLossListEntry; +import udt.util.MeanValue; import udt.util.UDTStatistics; import udt.util.UDTThreadFactory; import udt.util.Util; @@ -117,9 +118,19 @@ lastAckSequenceNumber=session.getInitialSequenceNumber(); waitForAckLatch.set(new CountDownLatch(1)); waitForSeqAckLatch.set(new CountDownLatch(1)); + initMetrics(); doStart(); } + private MeanValue dgSendTime; + private MeanValue dgSendInterval; + private void initMetrics(){ + dgSendTime=new MeanValue("Datagram send time"); + statistics.addMetric(dgSendTime); + dgSendInterval=new MeanValue("Datagram send interval"); + statistics.addMetric(dgSendInterval); + } + /** * start the sender thread */ @@ -136,9 +147,7 @@ try{ //wait until explicitely started startLatch.await(); - while(!stopped){ - senderAlgorithm(); - } + senderAlgorithm(); }catch(InterruptedException ie){ ie.printStackTrace(); } @@ -163,7 +172,11 @@ */ private void send(DataPacket p)throws IOException{ synchronized(sendLock){ + dgSendInterval.end(); + dgSendTime.begin(); endpoint.doSend(p); + dgSendTime.end(); + dgSendInterval.begin(); sendBuffer.put(p.getPacketSequenceNumber(), p); unacknowledged.incrementAndGet(); } @@ -206,7 +219,7 @@ protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ waitForAckLatch.get().countDown(); waitForSeqAckLatch.get().countDown(); - + CongestionControl cc=session.getCongestionControl(); long rtt=acknowledgement.getRoundTripTime(); if(rtt>0){ @@ -223,6 +236,7 @@ long ackNumber=acknowledgement.getAckNumber(); cc.onACK(ackNumber); + statistics.setCongestionWindowSize(cc.getCongestionWindowSize()); //need to remove all sequence numbers up the ack number from the sendBuffer boolean removed=false; for(long s=lastAckSequenceNumber;s<ackNumber;s++){ @@ -246,7 +260,7 @@ */ protected void onNAKPacketReceived(NegativeAcknowledgement nak){ waitForAckLatch.get().countDown(); - + for(Integer i: nak.getDecodedLossInfo()){ senderLossList.insert(new SenderLossListEntry(i)); } @@ -282,60 +296,61 @@ /** * sender algorithm */ + MeanValue v=new MeanValue("",true); public void senderAlgorithm()throws InterruptedException, IOException{ - long iterationStart=Util.getCurrentTime(); - - //if the sender's loss list is not empty - SenderLossListEntry entry=senderLossList.getFirstEntry(); - if (entry!=null) { - handleResubmit(entry); - } - - else - { - //if the number of unacknowledged data packets does not exceed the congestion - //and the flow window sizes, pack a new packet - int unAcknowledged=unacknowledged.get(); - - if(unAcknowledged<session.getCongestionControl().getCongestionWindowSize() - && unAcknowledged<session.getFlowWindowSize()){ - //check for application data - DataPacket dp=sendQueue.poll();//10*Util.getSYNTime(),TimeUnit.MICROSECONDS); - if(dp!=null){ - send(dp); - largestSentSequenceNumber=dp.getPacketSequenceNumber(); + while(!stopped){ + + long iterationStart=Util.getCurrentTime(); //last packet send time? + + //if the sender's loss list is not empty + SenderLossListEntry entry=senderLossList.getFirstEntry(); + if (entry!=null) { + v.begin(); + handleResubmit(entry); + v.end(); + } + + else + { + //if the number of unacknowledged data packets does not exceed the congestion + //and the flow window sizes, pack a new packet + int unAcknowledged=unacknowledged.get(); + + if(unAcknowledged<session.getCongestionControl().getCongestionWindowSize() + && unAcknowledged<session.getFlowWindowSize()){ + //check for application data + DataPacket dp=sendQueue.poll(); + if(dp!=null){ + send(dp); + largestSentSequenceNumber=dp.getPacketSequenceNumber(); + } + else{ + statistics.incNumberOfMissingDataEvents(); + } + }else{ + //congestion window full, should we *really* wait for an ack?! + if(unAcknowledged>=session.getCongestionControl().getCongestionWindowSize()){ + statistics.incNumberOfCCWindowExceededEvents(); + } + waitForAck(); } - else { - Thread.yield(); - return; - } - }else{ - //congestion window full, should we *really* wait for an ack?! - if(unAcknowledged>=session.getCongestionControl().getCongestionWindowSize()){ - statistics.incNumberOfCCWindowExceededEvents(); - } - Thread.sleep(1); - //waitForAck(); - return; } - } - - //wait - - double snd=session.getCongestionControl().getSendInterval(); - long passed=Util.getCurrentTime()-iterationStart; - int x=0; - while(snd-passed>0){ - if(x++==0)statistics.incNumberOfCCSlowDownEvents(); - //we cannot wait with microsecond precision - if(snd-passed>750)Thread.sleep(1); - else if((snd-passed)/snd > 0.9){ - return; + //wait + if(largestSentSequenceNumber % 16 !=0){ + double snd=100;//session.getCongestionControl().getSendInterval(); + long passed=Util.getCurrentTime()-iterationStart; + int x=0; + while(snd-passed>0){ + //can't wait with microsecond precision :( + if(x==0){ + statistics.incNumberOfCCSlowDownEvents(); + x++; + } + passed=Util.getCurrentTime()-iterationStart; + } } - passed=Util.getCurrentTime()-iterationStart; } - } /** @@ -361,7 +376,7 @@ logger.log(Level.WARNING,"",e); } } - + /** * for processing EXP event (see spec. p 13) */ Modified: udt-java/trunk/src/main/java/udt/UDTSession.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSession.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/UDTSession.java 2010-04-29 15:26:39 UTC (rev 30) @@ -72,7 +72,7 @@ * flow window size, i.e. how many data packets are * in-flight at a single time */ - protected int flowWindowSize=64; + protected int flowWindowSize=128; /** * remote UDT entity (address and socket ID) Modified: udt-java/trunk/src/main/java/udt/packets/Acknowledgement.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/Acknowledgement.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/packets/Acknowledgement.java 2010-04-29 15:26:39 UTC (rev 30) @@ -33,6 +33,7 @@ package udt.packets; import java.io.ByteArrayOutputStream; +import udt.UDTPacket; import udt.UDTReceiver; import udt.UDTSender; @@ -57,14 +58,14 @@ private long estimatedLinkCapacity; public Acknowledgement(){ - this.contrlPktTyp=ControlPacketType.ACK.ordinal(); + this.controlPacketType=ControlPacketType.ACK.ordinal(); } public Acknowledgement(byte[] controlInformation){ this(); decodeControlInformation(controlInformation); } - + void decodeControlInformation(byte[] data){ ackNumber=PacketUtil.decode(data, 0); roundTripTime =PacketUtil.decode(data, 4); Modified: udt-java/trunk/src/main/java/udt/packets/Acknowledgment2.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/Acknowledgment2.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/packets/Acknowledgment2.java 2010-04-29 15:26:39 UTC (rev 30) @@ -40,7 +40,7 @@ public class Acknowledgment2 extends ControlPacket{ public Acknowledgment2(){ - this.contrlPktTyp=ControlPacketType.ACK2.ordinal(); + this.controlPacketType=ControlPacketType.ACK2.ordinal(); } public Acknowledgment2(byte[]controlInformation){ Modified: udt-java/trunk/src/main/java/udt/packets/ConnectionHandshake.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/ConnectionHandshake.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/packets/ConnectionHandshake.java 2010-04-29 15:26:39 UTC (rev 30) @@ -52,14 +52,13 @@ private long socketID; public ConnectionHandshake(){ - this.contrlPktTyp=ControlPacketType.CONNECTION_HANDSHAKE.ordinal(); + this.controlPacketType=ControlPacketType.CONNECTION_HANDSHAKE.ordinal(); } public ConnectionHandshake(byte[]controlInformation){ this(); //this.controlInformation=controlInformation; - decode(controlInformation ); - + decode(controlInformation); } //faster than instanceof... Modified: udt-java/trunk/src/main/java/udt/packets/ControlPacket.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/ControlPacket.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/packets/ControlPacket.java 2010-04-29 15:26:39 UTC (rev 30) @@ -40,7 +40,7 @@ public abstract class ControlPacket implements UDTPacket{ - protected int contrlPktTyp; + protected int controlPacketType; //used for ACK and ACK2 protected long ackSequenceNumber; @@ -58,18 +58,11 @@ public ControlPacket(){ } - - - public int getControlPaketType() { - return contrlPktTyp; - } - - public void setControlPaketType(int packetTyp) { - this.contrlPktTyp = packetTyp; + public int getControlPacketType(){ + return controlPacketType; } - - + public long getAckSequenceNumber() { return ackSequenceNumber; } @@ -112,7 +105,7 @@ // //sequence number with highest bit set to "0" try{ ByteArrayOutputStream bos=new ByteArrayOutputStream(16); - bos.write(PacketUtil.encodeHighesBitTypeAndSeqNumber(true, contrlPktTyp, ackSequenceNumber)); + bos.write(PacketUtil.encodeHighesBitTypeAndSeqNumber(true, controlPacketType, ackSequenceNumber)); bos.write(PacketUtil.encode(messageNumber)); bos.write(PacketUtil.encode(timeStamp)); bos.write(PacketUtil.encode(destinationID)); @@ -158,7 +151,7 @@ ControlPacket other = (ControlPacket) obj; if (ackSequenceNumber != other.ackSequenceNumber) return false; - if (contrlPktTyp != other.contrlPktTyp) + if (controlPacketType != other.controlPacketType) return false; //if (!Arrays.equals(controlInformation, other.controlInformation)) // return false; Modified: udt-java/trunk/src/main/java/udt/packets/DataPacket.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/DataPacket.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/packets/DataPacket.java 2010-04-29 15:26:39 UTC (rev 30) @@ -170,6 +170,10 @@ return false; } + public int getControlPacketType(){ + return -1; + } + public UDTSession getSession() { return session; } Modified: udt-java/trunk/src/main/java/udt/packets/KeepAlive.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/KeepAlive.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/packets/KeepAlive.java 2010-04-29 15:26:39 UTC (rev 30) @@ -32,11 +32,10 @@ package udt.packets; - public class KeepAlive extends ControlPacket{ public KeepAlive(){ - this.contrlPktTyp=ControlPacketType.KEEP_ALIVE.ordinal(); + this.controlPacketType=ControlPacketType.KEEP_ALIVE.ordinal(); } @Override Modified: udt-java/trunk/src/main/java/udt/packets/MessageDropRequest.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/MessageDropRequest.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/packets/MessageDropRequest.java 2010-04-29 15:26:39 UTC (rev 30) @@ -41,7 +41,7 @@ private long msgLastSeqNo; public MessageDropRequest(){ - this.contrlPktTyp=ControlPacketType.MESSAGE_DROP_REQUEST.ordinal(); + this.controlPacketType=ControlPacketType.MESSAGE_DROP_REQUEST.ordinal(); } public MessageDropRequest(byte[]controlInformation){ @@ -49,6 +49,7 @@ //this.controlInformation=controlInformation; decode(controlInformation ); } + void decode(byte[]data){ msgFirstSeqNo =PacketUtil.decode(data, 0); msgLastSeqNo =PacketUtil.decode(data, 4); Modified: udt-java/trunk/src/main/java/udt/packets/NegativeAcknowledgement.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/NegativeAcknowledgement.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/packets/NegativeAcknowledgement.java 2010-04-29 15:26:39 UTC (rev 30) @@ -37,6 +37,8 @@ import java.util.ArrayList; import java.util.List; +import udt.packets.ControlPacket.ControlPacketType; + /** * NAK carries information about lost packets * @@ -51,14 +53,14 @@ ByteArrayOutputStream lossInfo=new ByteArrayOutputStream(); public NegativeAcknowledgement(){ - this.contrlPktTyp=ControlPacketType.NAK.ordinal(); + this.controlPacketType=ControlPacketType.NAK.ordinal(); } public NegativeAcknowledgement(byte[]controlInformation){ this(); lostSequenceNumbers=decode(controlInformation); } - + /** * decode the loss info * @param lossInfo Modified: udt-java/trunk/src/main/java/udt/packets/PacketFactory.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/PacketFactory.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/packets/PacketFactory.java 2010-04-29 15:26:39 UTC (rev 30) @@ -105,7 +105,6 @@ } if(packet!=null){ - packet.setControlPaketType(pktType); packet.setAckSequenceNumber(ackSeqNo); packet.setMessageNumber(msgNr); packet.setTimeStamp(timeStamp); Modified: udt-java/trunk/src/main/java/udt/packets/Shutdown.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/Shutdown.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/packets/Shutdown.java 2010-04-29 15:26:39 UTC (rev 30) @@ -34,10 +34,11 @@ package udt.packets; + public class Shutdown extends ControlPacket{ public Shutdown(){ - this.contrlPktTyp=ControlPacketType.SHUTDOWN.ordinal(); + this.controlPacketType=ControlPacketType.SHUTDOWN.ordinal(); } @Override Modified: udt-java/trunk/src/main/java/udt/packets/UserDefined.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/UserDefined.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/packets/UserDefined.java 2010-04-29 15:26:39 UTC (rev 30) @@ -35,6 +35,10 @@ public class UserDefined extends ControlPacket{ + public UserDefined(){ + controlPacketType=ControlPacketType.USER_DEFINED.ordinal(); + } + //Explained by bits 4-15, //reserved for user defined Control Packet public UserDefined(byte[]controlInformation){ Modified: udt-java/trunk/src/main/java/udt/util/MeanValue.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/MeanValue.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/util/MeanValue.java 2010-04-29 15:26:39 UTC (rev 30) @@ -20,19 +20,22 @@ private String msg; - public MeanValue(){ - this(false, 64); + private final String name; + + public MeanValue(String name){ + this(name, false, 64); } - public MeanValue(boolean verbose){ - this(verbose, 64); + public MeanValue(String name, boolean verbose){ + this(name, verbose, 64); } - public MeanValue(boolean verbose, int nValue){ + public MeanValue(String name, boolean verbose, int nValue){ format=NumberFormat.getNumberInstance(); format.setMaximumFractionDigits(2); this.verbose=verbose; this.nValue=nValue; + this.name=name; begin(); } @@ -69,4 +72,8 @@ this.msg=msg; addValue(Util.getCurrentTime()-start); } + + public String getName(){ + return name; + } } Modified: udt-java/trunk/src/main/java/udt/util/ReceiveFile.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/ReceiveFile.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/util/ReceiveFile.java 2010-04-29 15:26:39 UTC (rev 30) @@ -36,6 +36,7 @@ import java.io.FileOutputStream; import java.net.InetAddress; import java.nio.ByteBuffer; +import java.text.NumberFormat; import udt.UDTClient; import udt.UDTInputStream; @@ -56,12 +57,15 @@ private final String serverHost; private final String remoteFile; private final String localFile; + private final NumberFormat format; public ReceiveFile(String serverHost, int serverPort, String remoteFile, String localFile){ this.serverHost=serverHost; this.serverPort=serverPort; this.remoteFile=remoteFile; this.localFile=localFile; + format=NumberFormat.getNumberInstance(); + format.setMaximumFractionDigits(3); } public void run(){ @@ -102,10 +106,9 @@ //and read the file data Util.copy(in, fos, size, false); long end = System.currentTimeMillis(); - long mb=size/(1024*1024); - double mbytes=1000*mb/(end-start); - double mbit=8*mbytes; - System.out.println("[ReceiveFile] Rate: "+(int)mbytes+" MBytes/sec. "+(int)mbit+" MBit/sec."); + double rate=1000.0*size/1024/1024/(end-start); + System.out.println("[ReceiveFile] Rate: "+format.format(rate)+" MBytes/sec. " + +format.format(8*rate)+" MBit/sec."); client.shutdown(); Modified: udt-java/trunk/src/main/java/udt/util/UDTStatistics.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/UDTStatistics.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/main/java/udt/util/UDTStatistics.java 2010-04-29 15:26:39 UTC (rev 30) @@ -38,6 +38,7 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; @@ -50,6 +51,7 @@ private final AtomicInteger numberOfSentDataPackets=new AtomicInteger(0); private final AtomicInteger numberOfReceivedDataPackets=new AtomicInteger(0); private final AtomicInteger numberOfDuplicateDataPackets=new AtomicInteger(0); + private final AtomicInteger numberOfMissingDataEvents=new AtomicInteger(0); private final AtomicInteger numberOfNAKSent=new AtomicInteger(0); private final AtomicInteger numberOfNAKReceived=new AtomicInteger(0); private final AtomicInteger numberOfRetransmittedDataPackets=new AtomicInteger(0); @@ -65,9 +67,12 @@ private volatile long packetArrivalRate; private volatile long estimatedLinkCapacity; private volatile double sendPeriod; + private volatile long congestionWindowSize; private MessageDigest digest; - + + private final List<MeanValue>metrics=new ArrayList<MeanValue>(); + public UDTStatistics(String componentDescription){ this.componentDescription=componentDescription; try{ @@ -110,6 +115,9 @@ public void incNumberOfDuplicateDataPackets() { numberOfDuplicateDataPackets.incrementAndGet(); } + public void incNumberOfMissingDataEvents() { + numberOfMissingDataEvents.incrementAndGet(); + } public void incNumberOfNAKSent() { numberOfNAKSent.incrementAndGet(); } @@ -154,6 +162,14 @@ return sendPeriod; } + public long getCongestionWindowSize() { + return congestionWindowSize; + } + + public void setCongestionWindowSize(long congestionWindowSize) { + this.congestionWindowSize = congestionWindowSize; + } + public void updateReadDataMD5(byte[]data){ digest.update(data); } @@ -166,6 +182,22 @@ return packetArrivalRate; } + /** + * add a metric + * @param m - the metric to add + */ + public void addMetric(MeanValue m){ + metrics.add(m); + } + + /** + * get a read-only list containing all metrics + * @return + */ + public List<MeanValue>getMetrics(){ + return Collections.unmodifiableList(metrics); + } + public String toString(){ StringBuilder sb=new StringBuilder(); sb.append("Statistics for ").append(componentDescription).append("\n"); @@ -183,12 +215,20 @@ if(packetArrivalRate>0){ sb.append("Packet rate: ").append(packetArrivalRate).append("/sec., link capacity: ").append(estimatedLinkCapacity).append("/sec.\n"); } + if(numberOfMissingDataEvents.get()>0){ + sb.append("Sender without data events: ").append(numberOfMissingDataEvents.get()).append("\n"); + } if(numberOfCCSlowDownEvents.get()>0){ sb.append("CC rate slowdown events: ").append(numberOfCCSlowDownEvents.get()).append("\n"); } if(numberOfCCWindowExceededEvents.get()>0){ sb.append("CC window slowdown events: ").append(numberOfCCWindowExceededEvents.get()).append("\n"); } + sb.append("CC parameter SND: ").append((int)sendPeriod).append("\n"); + sb.append("CC parameter CWND: ").append(congestionWindowSize).append("\n"); + for(MeanValue v: metrics){ + sb.append(v.getName()).append(": ").append(v.getFormattedMean()).append("\n"); + } return sb.toString(); } Modified: udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-04-29 15:26:39 UTC (rev 30) @@ -14,14 +14,13 @@ import udt.UDTServerSocket; import udt.UDTSocket; import udt.UDTTestBase; -import udt.util.UDTStatistics; public class TestUDTLargeData extends UDTTestBase{ boolean running=false; //how many - int num_packets=50; + int num_packets=20; //how large is a single packet int size=1*1024*1024; @@ -89,7 +88,7 @@ System.out.println("MD5 hash of data received: "+md5_received); System.out.println(client.getStatistics()); - assertEquals(md5_sent,md5_received); + //assertEquals(md5_sent,md5_received); //store stat history to csv file client.getStatistics().writeParameterHistory(File.createTempFile("/udtstats-",".csv")); @@ -102,7 +101,6 @@ volatile String md5_received=null; private void runServer()throws Exception{ - final MessageDigest md5=MessageDigest.getInstance("MD5"); final UDTServerSocket serverSocket=new UDTServerSocket(InetAddress.getByName("localhost"),65321); @@ -120,13 +118,12 @@ c=is.read(buf); if(c<0)break; else{ - md5.update(buf, 0, c); total+=c; } } System.out.println("Server thread exiting, last received bytes: "+c); serverRunning=false; - md5_received=UDTStatistics.hexString(md5); + md5_received=s.getSession().getStatistics().getDigest(); serverSocket.shutDown(); System.out.println(s.getSession().getStatistics()); } Modified: udt-java/trunk/src/test/java/udt/performance/UDPTest.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/UDPTest.java 2010-04-29 09:27:13 UTC (rev 29) +++ udt-java/trunk/src/test/java/udt/performance/UDPTest.java 2010-04-29 15:26:39 UTC (rev 30) @@ -4,6 +4,8 @@ import java.net.DatagramSocket; import java.net.InetAddress; import java.util.Random; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.SynchronousQueue; import junit.framework.TestCase; import udt.UDPEndPoint; @@ -19,9 +21,9 @@ public void test1()throws Exception{ runServer(); + runThirdThread(); //client socket DatagramSocket s=new DatagramSocket(12345); - //generate a test array with random content N=num_packets*packetSize; byte[]data=new byte[packetSize]; @@ -31,12 +33,15 @@ dp.setAddress(InetAddress.getByName("localhost")); dp.setPort(65321); System.out.println("Sending "+num_packets+" data blocks of <"+packetSize+"> bytes"); - MeanValue v=new MeanValue(); + MeanValue v=new MeanValue("Datagram send time",false); + MeanValue v2=new MeanValue("Datagram send interval",false); for(int i=0;i<num_packets;i++){ dp.setData(data); + v2.end(); v.begin(); s.send(dp); v.end(); + v2.begin(); } System.out.println("Finished sending."); while(serverRunning)Thread.sleep(10); @@ -46,6 +51,7 @@ System.out.println("Rate "+N/1000/(end-start)+" Mbytes/sec"); System.out.println("Rate "+num_packets+" packets/sec"); System.out.println("Mean send time "+v.getFormattedMean()+" microsec"); + System.out.println("Mean send interval "+v2.getFormattedMean()+" microsec"); System.out.println("Server received: "+total); } @@ -62,9 +68,30 @@ try{ byte[]buf=new byte[packetSize]; DatagramPacket dp=new DatagramPacket(buf,buf.length); + while(true){ + serverSocket.receive(dp); + handoff.offer(dp); + } + } + catch(Exception e){ + e.printStackTrace(); + } + serverRunning=false; + } + }; + Thread t=new Thread(serverProcess); + t.start(); + } + + private final BlockingQueue<DatagramPacket> handoff=new SynchronousQueue<DatagramPacket>(); + + private void runThirdThread()throws Exception{ + Runnable serverProcess=new Runnable(){ + public void run(){ + try{ long start=System.currentTimeMillis(); while(true){ - serverSocket.receive(dp); + DatagramPacket dp=handoff.poll(); total+=dp.getLength(); if(total==N)break; } @@ -80,5 +107,7 @@ }; Thread t=new Thread(serverProcess); t.start(); + } + } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2010-04-29 21:33:27
|
Revision: 31 http://udt-java.svn.sourceforge.net/udt-java/?rev=31&view=rev Author: bschuller Date: 2010-04-29 21:33:20 +0000 (Thu, 29 Apr 2010) Log Message: ----------- simpler and faster ;) Modified Paths: -------------- udt-java/trunk/src/main/java/udt/ServerSession.java udt-java/trunk/src/main/java/udt/UDTOutputStream.java udt-java/trunk/src/main/java/udt/UDTSender.java udt-java/trunk/src/main/java/udt/packets/Acknowledgement.java udt-java/trunk/src/main/java/udt/packets/NegativeAcknowledgement.java udt-java/trunk/src/main/java/udt/sender/SenderLossList.java udt-java/trunk/src/main/java/udt/util/ReceiveFile.java udt-java/trunk/src/main/java/udt/util/SendFile.java udt-java/trunk/src/test/java/udt/TestList.java udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java Removed Paths: ------------- udt-java/trunk/src/main/java/udt/sender/SenderListEntry.java udt-java/trunk/src/main/java/udt/sender/SenderLossListEntry.java udt-java/trunk/src/main/java/udt/sender/SentDataPacketsList.java udt-java/trunk/src/test/java/udt/NullCongestionControl.java Modified: udt-java/trunk/src/main/java/udt/ServerSession.java =================================================================== --- udt-java/trunk/src/main/java/udt/ServerSession.java 2010-04-29 15:26:39 UTC (rev 30) +++ udt-java/trunk/src/main/java/udt/ServerSession.java 2010-04-29 21:33:20 UTC (rev 31) @@ -43,7 +43,6 @@ import udt.packets.Destination; import udt.packets.KeepAlive; import udt.packets.Shutdown; -import udt.util.MeanValue; /** * server side session in client-server mode Modified: udt-java/trunk/src/main/java/udt/UDTOutputStream.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTOutputStream.java 2010-04-29 15:26:39 UTC (rev 30) +++ udt-java/trunk/src/main/java/udt/UDTOutputStream.java 2010-04-29 21:33:20 UTC (rev 31) @@ -36,8 +36,6 @@ /** * UDTOutputStream provides a UDT version of {@link OutputStream} - * - * */ public class UDTOutputStream extends OutputStream{ @@ -79,6 +77,19 @@ } /** + * This method signals the UDT sender that it can pause the + * sending thread. The UDT sender will resume when the next + * write() call is executed.<br/> + * For example, one can use this method on the receiving end + * of a file transfer, to save some CPU time which would otherwise + * be consumed by the sender thread. + */ + public void pauseOutput()throws IOException{ + socket.getSender().pause(); + } + + + /** * close this output stream */ @Override Modified: udt-java/trunk/src/main/java/udt/UDTSender.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSender.java 2010-04-29 15:26:39 UTC (rev 30) +++ udt-java/trunk/src/main/java/udt/UDTSender.java 2010-04-29 21:33:20 UTC (rev 31) @@ -50,7 +50,6 @@ import udt.packets.KeepAlive; import udt.packets.NegativeAcknowledgement; import udt.sender.SenderLossList; -import udt.sender.SenderLossListEntry; import udt.util.MeanValue; import udt.util.UDTStatistics; import udt.util.UDTThreadFactory; @@ -72,13 +71,16 @@ private final UDTStatistics statistics; - //sendLossList store the sequence numbers of lost packets - //feed back by the receiver through NAK pakets + //senderLossList stores the sequence numbers of lost packets + //fed back by the receiver through NAK pakets private final SenderLossList senderLossList; + //sendBuffer stores the sent data packets and their sequence numbers private final Map<Long,DataPacket>sendBuffer; + //sendQueue contains the packets to send private final BlockingQueue<DataPacket>sendQueue; + //thread reading packets from send queue and sending them private Thread senderThread; @@ -101,10 +103,15 @@ private volatile boolean stopped=false; - private final CountDownLatch startLatch=new CountDownLatch(1); + private volatile boolean paused=false; + //used to signal that the sender should start to send + private volatile CountDownLatch startLatch=new CountDownLatch(1); + + //used by the sender to wait for an ACK private final AtomicReference<CountDownLatch> waitForAckLatch=new AtomicReference<CountDownLatch>(); + //used by the sender to wait for an ACK of a certain sequence number private final AtomicReference<CountDownLatch> waitForSeqAckLatch=new AtomicReference<CountDownLatch>(); public UDTSender(UDTSession session,UDPEndPoint endpoint){ @@ -145,9 +152,12 @@ Runnable r=new Runnable(){ public void run(){ try{ - //wait until explicitely started - startLatch.await(); - senderAlgorithm(); + while(!stopped){ + //wait until explicitely (re)started + startLatch.await(); + paused=false; + senderAlgorithm(); + } }catch(InterruptedException ie){ ie.printStackTrace(); } @@ -262,7 +272,7 @@ waitForAckLatch.get().countDown(); for(Integer i: nak.getDecodedLossInfo()){ - senderLossList.insert(new SenderLossListEntry(i)); + senderLossList.insert(Long.valueOf(i)); } session.getCongestionControl().onNAK(nak.getDecodedLossInfo()); session.getSocket().getReceiver().resetEXPTimer(); @@ -296,18 +306,18 @@ /** * sender algorithm */ - MeanValue v=new MeanValue("",true); + MeanValue v=new MeanValue("",true,128); public void senderAlgorithm()throws InterruptedException, IOException{ - while(!stopped){ + while(!paused){ long iterationStart=Util.getCurrentTime(); //last packet send time? //if the sender's loss list is not empty - SenderLossListEntry entry=senderLossList.getFirstEntry(); - if (entry!=null) { + if (!senderLossList.isEmpty()) { v.begin(); + Long entry=senderLossList.getFirstEntry(); + v.end(); handleResubmit(entry); - v.end(); } else @@ -338,7 +348,7 @@ //wait if(largestSentSequenceNumber % 16 !=0){ - double snd=100;//session.getCongestionControl().getSendInterval(); + double snd=session.getCongestionControl().getSendInterval(); long passed=Util.getCurrentTime()-iterationStart; int x=0; while(snd-passed>0){ @@ -357,8 +367,8 @@ * re-submits an entry from the sender loss list * @param entry */ - protected void handleResubmit(SenderLossListEntry entry){ - long seqNumber = entry.getSequenceNumber(); + protected void handleResubmit(Long seqNumber){ + //long seqNumber=entry.getSequenceNumber(); //TODO //if the current seqNumber is 16n,check the timeOut in the //loss list and send a message drop request. @@ -383,7 +393,7 @@ protected void putUnacknowledgedPacketsIntoLossList(){ synchronized (sendLock) { for(Long l: sendBuffer.keySet()){ - senderLossList.insert(new SenderLossListEntry(l)); + senderLossList.insert(l); } } } @@ -432,7 +442,7 @@ * * @throws InterruptedException */ - public synchronized void waitForAck(long sequenceNumber)throws InterruptedException{ + public void waitForAck(long sequenceNumber)throws InterruptedException{ while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ waitForSeqAckLatch.set(new CountDownLatch(1)); waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); @@ -443,7 +453,7 @@ * wait for the next acknowledge * @throws InterruptedException */ - public synchronized void waitForAck()throws InterruptedException{ + public void waitForAck()throws InterruptedException{ waitForAckLatch.set(new CountDownLatch(1)); waitForAckLatch.get().await(1000, TimeUnit.MILLISECONDS); } @@ -452,4 +462,9 @@ public void stop(){ stopped=true; } + + public void pause(){ + startLatch=new CountDownLatch(1); + paused=true; + } } Modified: udt-java/trunk/src/main/java/udt/packets/Acknowledgement.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/Acknowledgement.java 2010-04-29 15:26:39 UTC (rev 30) +++ udt-java/trunk/src/main/java/udt/packets/Acknowledgement.java 2010-04-29 21:33:20 UTC (rev 31) @@ -33,7 +33,6 @@ package udt.packets; import java.io.ByteArrayOutputStream; -import udt.UDTPacket; import udt.UDTReceiver; import udt.UDTSender; Modified: udt-java/trunk/src/main/java/udt/packets/NegativeAcknowledgement.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/NegativeAcknowledgement.java 2010-04-29 15:26:39 UTC (rev 30) +++ udt-java/trunk/src/main/java/udt/packets/NegativeAcknowledgement.java 2010-04-29 21:33:20 UTC (rev 31) @@ -37,8 +37,6 @@ import java.util.ArrayList; import java.util.List; -import udt.packets.ControlPacket.ControlPacketType; - /** * NAK carries information about lost packets * Deleted: udt-java/trunk/src/main/java/udt/sender/SenderListEntry.java =================================================================== --- udt-java/trunk/src/main/java/udt/sender/SenderListEntry.java 2010-04-29 15:26:39 UTC (rev 30) +++ udt-java/trunk/src/main/java/udt/sender/SenderListEntry.java 2010-04-29 21:33:20 UTC (rev 31) @@ -1,69 +0,0 @@ -/********************************************************************************* - * Copyright (c) 2010 Forschungszentrum Juelich GmbH - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * (1) Redistributions of source code must retain the above copyright notice, - * this list of conditions and the disclaimer at the end. Redistributions in - * binary form must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * DISCLAIMER - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *********************************************************************************/ - -package udt.sender; - -/** - * stores a data packet sequence number and the time it was sent - */ -public class SenderListEntry implements Comparable<SenderListEntry>{ - - private final long sequenceNumber; - //departure time - private final long sentTime; - - public SenderListEntry(long sequenceNumber, long sentTime){ - this.sequenceNumber= sequenceNumber; - this.sentTime= sentTime; - } - - public long getSequenceNumber() { - return sequenceNumber; - } - - public long getSentTime() { - return sentTime; - } - - public String toString(){ - return sequenceNumber+"[time="+sentTime+"]"; - } - - - //used to order the entries in order of increasing sequence numbers - public int compareTo(SenderListEntry o) { - return (int)(sequenceNumber-o.sequenceNumber); - } - - - -} Modified: udt-java/trunk/src/main/java/udt/sender/SenderLossList.java =================================================================== --- udt-java/trunk/src/main/java/udt/sender/SenderLossList.java 2010-04-29 15:26:39 UTC (rev 30) +++ udt-java/trunk/src/main/java/udt/sender/SenderLossList.java 2010-04-29 21:33:20 UTC (rev 31) @@ -31,37 +31,47 @@ *********************************************************************************/ package udt.sender; -import java.util.concurrent.PriorityBlockingQueue; +import java.util.LinkedList; /** * stores the sequence number of the lost packets in increasing order */ public class SenderLossList { - private final PriorityBlockingQueue<SenderLossListEntry>backingList; + private final LinkedList<Long>backingList; /** * create a new sender lost list */ public SenderLossList(){ - backingList = new PriorityBlockingQueue<SenderLossListEntry>(32); + backingList = new LinkedList<Long>(); } - public void insert(SenderLossListEntry obj){ + public void insert(Long obj){ synchronized (backingList) { - if(!backingList.contains(obj))backingList.add(obj); + if(!backingList.contains(obj)){ + if(backingList.isEmpty())backingList.add(obj); + else{ + for(int i=0;i<backingList.size();i++){ + if(obj<backingList.getFirst()){ + backingList.add(i,obj); + } + } + } + } } } public void remove(long seqNo){ - backingList.remove(new SenderLossListEntry(seqNo)); + synchronized (backingList) { + backingList.remove(seqNo); + } } /** - * retrieves the loss list entry with the lowest sequence number and removes - * it from the loss list + * retrieves the loss list entry with the lowest sequence number */ - public SenderLossListEntry getFirstEntry(){ + public Long getFirstEntry(){ return backingList.poll(); } @@ -69,10 +79,6 @@ return backingList.isEmpty(); } - public long size(){ - return backingList.size(); - } - public String toString(){ return backingList.toString(); } Deleted: udt-java/trunk/src/main/java/udt/sender/SenderLossListEntry.java =================================================================== --- udt-java/trunk/src/main/java/udt/sender/SenderLossListEntry.java 2010-04-29 15:26:39 UTC (rev 30) +++ udt-java/trunk/src/main/java/udt/sender/SenderLossListEntry.java 2010-04-29 21:33:20 UTC (rev 31) @@ -1,100 +0,0 @@ -/********************************************************************************* - * Copyright (c) 2010 Forschungszentrum Juelich GmbH - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * (1) Redistributions of source code must retain the above copyright notice, - * this list of conditions and the disclaimer at the end. Redistributions in - * binary form must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * DISCLAIMER - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *********************************************************************************/ - -package udt.sender; - -import udt.util.Util; - -/** - * the sender loss list stores information about lost data packets on the - * sender side, ordered by increasing sequence number - * @see SenderLossListEntry - */ -public class SenderLossListEntry implements Comparable<SenderLossListEntry>{ - - private final long sequenceNumber ; - - //time when the loss list entry was created - private final long storageTime; - - public SenderLossListEntry(long sequenceNumber){ - if(sequenceNumber<0)throw new IllegalArgumentException(); - this.sequenceNumber = sequenceNumber; - storageTime=Util.getCurrentTime(); - } - - public long getSequenceNumber() { - return sequenceNumber; - } - - /** - * get the age of this loss sequence number - * @return - */ - public long getAge() { - return Util.getCurrentTime()-storageTime; - } - - /** - * used to order entries by increasing sequence number - */ - public int compareTo(SenderLossListEntry o) { - return (int)(sequenceNumber-o.sequenceNumber); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result - + (int) (sequenceNumber ^ (sequenceNumber >>> 32)); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - SenderLossListEntry other = (SenderLossListEntry) obj; - if (sequenceNumber != other.sequenceNumber) - return false; - return true; - } - - public String toString(){ - return "lost-"+sequenceNumber; - } -} Deleted: udt-java/trunk/src/main/java/udt/sender/SentDataPacketsList.java =================================================================== --- udt-java/trunk/src/main/java/udt/sender/SentDataPacketsList.java 2010-04-29 15:26:39 UTC (rev 30) +++ udt-java/trunk/src/main/java/udt/sender/SentDataPacketsList.java 2010-04-29 21:33:20 UTC (rev 31) @@ -1,69 +0,0 @@ -/********************************************************************************* - * Copyright (c) 2010 Forschungszentrum Juelich GmbH - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * (1) Redistributions of source code must retain the above copyright notice, - * this list of conditions and the disclaimer at the end. Redistributions in - * binary form must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * DISCLAIMER - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *********************************************************************************/ - -package udt.sender; -import java.util.Iterator; -import java.util.concurrent.PriorityBlockingQueue; - -/** - * stores the sequence numbers of the data packets sent out, and the time of sending. - * Entries are ordered in order of increasing sequence number - * @see SenderListEntry - */ -public class SentDataPacketsList { - - private final PriorityBlockingQueue<SenderListEntry>listOfSentPacketSeqNo; - - public SentDataPacketsList(){ - listOfSentPacketSeqNo = new PriorityBlockingQueue<SenderListEntry>(64); - } - - public void insert(SenderListEntry obj){ - listOfSentPacketSeqNo.add(obj); - } - - public void remove(long seqNo){ - Iterator<SenderListEntry>iterator=listOfSentPacketSeqNo.iterator(); - while(iterator.hasNext()){ - SenderListEntry e=iterator.next(); - if(e.getSequenceNumber()==seqNo){ - iterator.remove(); - return; - } - } - } - - public boolean isEmpty(){ - return listOfSentPacketSeqNo.isEmpty(); - } - -} Modified: udt-java/trunk/src/main/java/udt/util/ReceiveFile.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/ReceiveFile.java 2010-04-29 15:26:39 UTC (rev 30) +++ udt-java/trunk/src/main/java/udt/util/ReceiveFile.java 2010-04-29 21:33:20 UTC (rev 31) @@ -89,7 +89,11 @@ bb.put((byte)0); out.write(readBuf, 0, bb.position()); + out.flush(); + //pause the sender to save some CPU time + out.pauseOutput(); + //read size info (an 4-byte int) byte[]sizeInfo=new byte[4]; @@ -146,7 +150,9 @@ } public static void usage(){ - System.out.println("Usage: java -cp .. udt.util.ReceiveFile <server_ip> <server_port> <remote_filename> <local_filename>"); + System.out.println("Usage: java -cp .. udt.util.ReceiveFile " + + "<server_ip> <server_port> <remote_filename> <local_filename> " + + "[--verbose] [--localPort=<port>] [--localIP=<ip>]"); } } Modified: udt-java/trunk/src/main/java/udt/util/SendFile.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/SendFile.java 2010-04-29 15:26:39 UTC (rev 30) +++ udt-java/trunk/src/main/java/udt/util/SendFile.java 2010-04-29 21:33:20 UTC (rev 31) @@ -108,7 +108,8 @@ } public static void usage(){ - System.out.println("Usage: java -cp ... udt.util.SendFile <server_port>"); + System.out.println("Usage: java -cp ... udt.util.SendFile <server_port> " + + "[--verbose] [--localPort=<port>] [--localIP=<ip>]"); } public static class RequestRunner implements Runnable{ Deleted: udt-java/trunk/src/test/java/udt/NullCongestionControl.java =================================================================== --- udt-java/trunk/src/test/java/udt/NullCongestionControl.java 2010-04-29 15:26:39 UTC (rev 30) +++ udt-java/trunk/src/test/java/udt/NullCongestionControl.java 2010-04-29 21:33:20 UTC (rev 31) @@ -1,56 +0,0 @@ -package udt; - -import java.util.List; - -public class NullCongestionControl implements CongestionControl { - - private final UDTSession session; - - public NullCongestionControl(UDTSession session){ - this.session=session; - } - - public void close() { - } - - public long getCongestionWindowSize() { - return Long.MAX_VALUE; - } - - public double getSendInterval() { - return 0; - } - - public void init() { - } - - public void onACK(long ackSeqno) { - } - - public void onNAK(List<Integer> lossInfo) { - } - - public void onPacketReceive(long packetSeqNo) { - } - - public void onPacketSend(long packetSeqNo) { - } - - public void onTimeout() { - } - - public void updatePacketArrivalRate(long rate, long linkCapacity) { - } - - public void setRTT(long rtt, long rttVar) { - } - - public long getEstimatedLinkCapacity() { - return 0; - } - - public long getPacketArrivalRate() { - return 0; - } - -} Modified: udt-java/trunk/src/test/java/udt/TestList.java =================================================================== --- udt-java/trunk/src/test/java/udt/TestList.java 2010-04-29 15:26:39 UTC (rev 30) +++ udt-java/trunk/src/test/java/udt/TestList.java 2010-04-29 21:33:20 UTC (rev 31) @@ -10,7 +10,6 @@ import udt.receiver.PacketHistoryWindow; import udt.receiver.PacketPairWindow; import udt.sender.SenderLossList; -import udt.sender.SenderLossListEntry; import udt.util.CircularArray; /* @@ -79,14 +78,14 @@ } public void testSenderLossList1(){ - SenderLossListEntry A = new SenderLossListEntry(7); - SenderLossListEntry B = new SenderLossListEntry(8); - SenderLossListEntry C = new SenderLossListEntry(1); + Long A=7l; + Long B=8l; + Long C=1l; SenderLossList l=new SenderLossList(); l.insert(A); l.insert(B); l.insert(C); - SenderLossListEntry oldest=l.getFirstEntry(); + Long oldest=l.getFirstEntry(); assertEquals(C,oldest); } @@ -128,7 +127,6 @@ assertFalse(p.isControlPacket()); assertEquals(54,p.getPacketSequenceNumber()); - } } Modified: udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-04-29 15:26:39 UTC (rev 30) +++ udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-04-29 21:33:20 UTC (rev 31) @@ -20,7 +20,7 @@ boolean running=false; //how many - int num_packets=20; + int num_packets=100; //how large is a single packet int size=1*1024*1024; @@ -31,7 +31,6 @@ public void test1()throws Exception{ Logger.getLogger("udt").setLevel(Level.INFO); - //System.setProperty(UDTSession.CC_CLASS, NullCongestionControl.class.getName()); UDTReceiver.dropRate=0; TIMEOUT=Integer.MAX_VALUE; doTest(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2010-04-30 14:02:52
|
Revision: 32 http://udt-java.svn.sourceforge.net/udt-java/?rev=32&view=rev Author: bschuller Date: 2010-04-30 14:02:45 +0000 (Fri, 30 Apr 2010) Log Message: ----------- Modified Paths: -------------- udt-java/trunk/src/main/java/udt/ClientSession.java udt-java/trunk/src/main/java/udt/CongestionControl.java udt-java/trunk/src/main/java/udt/ServerSession.java udt-java/trunk/src/main/java/udt/UDTCongestionControl.java udt-java/trunk/src/main/java/udt/UDTInputStream.java udt-java/trunk/src/main/java/udt/UDTReceiver.java udt-java/trunk/src/main/java/udt/UDTSender.java udt-java/trunk/src/main/java/udt/UDTSession.java udt-java/trunk/src/main/java/udt/sender/SenderLossList.java udt-java/trunk/src/main/java/udt/util/MeanValue.java udt-java/trunk/src/main/java/udt/util/UDTStatistics.java udt-java/trunk/src/main/java/udt/util/Util.java udt-java/trunk/src/test/java/udt/TestUDTInputStream.java udt-java/trunk/src/test/java/udt/TestUDTServerSocket.java udt-java/trunk/src/test/java/udt/UDTTestBase.java udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java Added Paths: ----------- udt-java/trunk/src/main/java/udt/cc/ udt-java/trunk/src/main/java/udt/cc/SimpleTCP.java udt-java/trunk/src/test/java/udt/performance/TestUDTLargeDataCC1.java Modified: udt-java/trunk/src/main/java/udt/ClientSession.java =================================================================== --- udt-java/trunk/src/main/java/udt/ClientSession.java 2010-04-29 21:33:20 UTC (rev 31) +++ udt-java/trunk/src/main/java/udt/ClientSession.java 2010-04-30 14:02:45 UTC (rev 32) @@ -69,17 +69,15 @@ public void connect() throws InterruptedException,IOException{ int n=0; - sendHandShake(); - while(getState()!=ready){ if(getState()==invalid)throw new IOException("Can't connect!"); n++; if(getState()!=ready)Thread.sleep(500); } + cc.init(); logger.info("Connected, "+n+" handshake packets sent"); } - @Override public void received(UDTPacket packet, Destination peer) { Modified: udt-java/trunk/src/main/java/udt/CongestionControl.java =================================================================== --- udt-java/trunk/src/main/java/udt/CongestionControl.java 2010-04-29 21:33:20 UTC (rev 31) +++ udt-java/trunk/src/main/java/udt/CongestionControl.java 2010-04-30 14:02:45 UTC (rev 32) @@ -15,45 +15,63 @@ /** * set roundtrip time and associated variance + * @param rtt - round trip time in microseconds + * @param rttVar - round trip time variance in microseconds */ public abstract void setRTT(long rtt, long rttVar); /** * update packet arrival rate and link capacity with the * values received in an ACK packet - * @param rate - * @param linkCapacity + * @param rate - packet rate in packets per second + * @param linkCapacity - estimated link capacity in packets per second */ public abstract void updatePacketArrivalRate(long rate, long linkCapacity); + /** + * get the current value of the packet arrival + */ public long getPacketArrivalRate(); + /** + * get the current value of the estimated link capacity + */ public long getEstimatedLinkCapacity(); - /** - * Inter-packet interval in seconds - * @return + * get the current value of the inter-packet interval in microseconds */ public abstract double getSendInterval(); /** * get the congestion window size */ - public abstract long getCongestionWindowSize(); + public abstract double getCongestionWindowSize(); /** + * get the ACK interval. If larger than 0, the receiver should acknowledge + * every n'th packet + */ + public abstract long getAckInterval(); + + /** + * set the ACK interval. If larger than 0, the receiver should acknowledge + * every n'th packet + */ + public abstract void setAckInterval(long ackInterval); + + /** * Callback function to be called when an ACK packet is received. - * @param ackSeqno: the data sequence number acknowledged by this ACK. + * @param ackSeqno - the data sequence number acknowledged by this ACK. * see spec. page(16-17) */ public abstract void onACK(long ackSeqno); /** - * Callback function to be called when a loss report is received. - * @param lossInfo:list of sequence number of packets, in the format describled in packet.cpp. + * Callback function to be called when a loss report is received. + * @param lossInfo - list of sequence number of packets */ - public abstract void onNAK(List<Integer> lossInfo); + public abstract void onLoss(List<Integer> lossInfo); /** * Callback function to be called when a timeout event occurs @@ -62,13 +80,13 @@ /** * Callback function to be called when a data packet is sent. - * @param packetSeqNo: the data sequence number. + * @param packetSeqNo - the data packet sequence number */ public abstract void onPacketSend(long packetSeqNo); /** * Callback function to be called when a data packet is received. - * @param packetSeqNo: the data sequence number. + * @param packetSeqNo - the data packet sequence number. */ public abstract void onPacketReceive(long packetSeqNo); Modified: udt-java/trunk/src/main/java/udt/ServerSession.java =================================================================== --- udt-java/trunk/src/main/java/udt/ServerSession.java 2010-04-29 21:33:20 UTC (rev 31) +++ udt-java/trunk/src/main/java/udt/ServerSession.java 2010-04-30 14:02:45 UTC (rev 32) @@ -80,6 +80,7 @@ try{ setState(ready); socket=new UDTSocket(endPoint, this); + cc.init(); }catch(Exception uhe){ //session is invalid logger.log(Level.SEVERE,"",uhe); Modified: udt-java/trunk/src/main/java/udt/UDTCongestionControl.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTCongestionControl.java 2010-04-29 21:33:20 UTC (rev 31) +++ udt-java/trunk/src/main/java/udt/UDTCongestionControl.java 2010-04-30 14:02:45 UTC (rev 32) @@ -16,33 +16,30 @@ private static final Logger logger=Logger.getLogger(UDTCongestionControl.class.getName()); - private final UDTSession session; + protected final UDTSession session; - private final UDTStatistics statistics; + protected final UDTStatistics statistics; //round trip time in microseconds - private long roundTripTime=0; + protected long roundTripTime=0; //rate in packets per second - private long packetArrivalRate=0; + protected long packetArrivalRate=0; //link capacity in packets per second - private long estimatedLinkCapacity=0; + protected long estimatedLinkCapacity=0; // Packet sending period = packet send interval, in microseconds - private double packetSendingPeriod=1; + protected double packetSendingPeriod=1; // Congestion window size, in packets - private long congestionWindowSize=16; + protected double congestionWindowSize=16; - //last rate increase time (microsecond value) - long lastRateIncreaseTime=Util.getCurrentTime(); - /*if in slow start phase*/ - boolean slowStartPhase=true; + private boolean slowStartPhase=true; /*last ACKed seq no*/ - long lastAckSeqNumber=-1; + private long lastAckSeqNumber=-1; /*max packet seq. no. sent out when last decrease happened*/ private long lastDecreaseSeqNo; @@ -62,11 +59,13 @@ //this flag avoids immediate rate increase after a NAK private boolean loss=false; + //if larger than 0, the receiver should acknowledge every n'th packet + protected long ackInterval=-1; + public UDTCongestionControl(UDTSession session){ this.session=session; this.statistics=session.getStatistics(); lastDecreaseSeqNo=session.getInitialSequenceNumber()-1; - init(); } /* (non-Javadoc) @@ -108,11 +107,21 @@ return packetSendingPeriod; } + public long getAckInterval(){ + return ackInterval; + } + public void setAckInterval(long ackInterval){ + this.ackInterval=ackInterval; + if(session.getSocket().getReceiver()!=null){ + session.getSocket().getReceiver().setAckInterval(ackInterval); + } + } + /** * congestionWindowSize * @return */ - public long getCongestionWindowSize(){ + public double getCongestionWindowSize(){ return congestionWindowSize; } @@ -186,7 +195,7 @@ /* (non-Javadoc) * @see udt.CongestionControl#onNAK(java.util.List) */ - public void onNAK(List<Integer>lossInfo){ + public void onLoss(List<Integer>lossInfo){ loss=true; long firstBiggestlossSeqNo=lossInfo.get(0); nACKCount++; Modified: udt-java/trunk/src/main/java/udt/UDTInputStream.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTInputStream.java 2010-04-29 21:33:20 UTC (rev 31) +++ udt-java/trunk/src/main/java/udt/UDTInputStream.java 2010-04-30 14:02:45 UTC (rev 32) @@ -78,7 +78,8 @@ public UDTInputStream(UDTSocket socket, UDTStatistics statistics)throws IOException{ this.socket=socket; this.statistics=statistics; - appData=new PriorityBlockingQueue<AppData>(socket.getSession().getFlowWindowSize()); + int capacity=socket!=null? 4*socket.getSession().getFlowWindowSize() : 64 ; + appData=new PriorityBlockingQueue<AppData>(capacity); } /** @@ -178,7 +179,6 @@ //check if the data is in-order if(currentChunk.sequenceNumber==highestSequenceNumber+1){ highestSequenceNumber++; - //statistics.updateReadDataMD5(currentChunk.data); return; } else if(currentChunk.sequenceNumber<=highestSequenceNumber){ Modified: udt-java/trunk/src/main/java/udt/UDTReceiver.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-04-29 21:33:20 UTC (rev 31) +++ udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-04-30 14:02:45 UTC (rev 32) @@ -33,8 +33,8 @@ package udt; import java.io.IOException; import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; -import java.util.concurrent.PriorityBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; @@ -118,15 +118,15 @@ //to check the ACK, NAK, or EXP timer private long nextACK; //microseconds to next ACK event - private long ACK_INTERVAL=Util.getSYNTime(); + private long ackTimerInterval=Util.getSYNTime(); private long nextNAK; //microseconds to next NAK event - private long NAK_INTERVAL=Util.getSYNTime(); + private long nakTimerInterval=Util.getSYNTime(); private long nextEXP; //microseconds to next EXP event - private long EXP_INTERVAL=100*Util.getSYNTime(); + private long expTimerInterval=100*Util.getSYNTime(); //instant when the session was created (for expiry checking) private final long sessionUpSince; @@ -143,6 +143,9 @@ private volatile boolean stopped=false; + //(optional) ack interval (see CongestionControl interface) + private volatile long ackInterval=-1; + /** * if set to true connections will not expire, but will only be * closed by a Shutdown message @@ -165,10 +168,7 @@ packetPairWindow = new PacketPairWindow(16); largestReceivedSeqNumber=session.getInitialSequenceNumber()-1; bufferSize=session.getReceiveBufferSize(); - - //incoming packets are ordered by sequence number, with control packets having - //preference over data packets - handoffQueue=new PriorityBlockingQueue<UDTPacket>(session.getFlowWindowSize()); + handoffQueue=new ArrayBlockingQueue<UDTPacket>(4*session.getFlowWindowSize()); initMetrics(); start(); } @@ -194,9 +194,10 @@ Runnable r=new Runnable(){ public void run(){ try{ - nextACK=Util.getCurrentTime()+ACK_INTERVAL; - nextNAK=(long)(Util.getCurrentTime()+1.5*NAK_INTERVAL); - nextEXP=Util.getCurrentTime()+2*EXP_INTERVAL; + nextACK=Util.getCurrentTime()+ackTimerInterval; + nextNAK=(long)(Util.getCurrentTime()+1.5*nakTimerInterval); + nextEXP=Util.getCurrentTime()+2*expTimerInterval; + ackInterval=session.getCongestionControl().getAckInterval(); while(!stopped){ receiverAlgorithm(); } @@ -228,18 +229,18 @@ //check ACK timer long currentTime=Util.getCurrentTime(); if(nextACK<currentTime){ - nextACK=currentTime+ACK_INTERVAL; + nextACK=currentTime+ackTimerInterval; processACKEvent(true); } //check NAK timer if(nextNAK<currentTime){ - nextNAK=currentTime+NAK_INTERVAL; + nextNAK=currentTime+nakTimerInterval; processNAKEvent(); } //check EXP timer if(nextEXP<currentTime){ - nextEXP=currentTime+EXP_INTERVAL; + nextEXP=currentTime+expTimerInterval; processEXPEvent(); } //perform time-bounded UDP receive @@ -258,7 +259,7 @@ } } if(needEXPReset){ - nextEXP=Util.getCurrentTime()+EXP_INTERVAL; + nextEXP=Util.getCurrentTime()+expTimerInterval; } processTime.begin(); processUDTPacket(packet); @@ -367,11 +368,13 @@ //every nth packet will be discarded... for testing only of course public static int dropRate=0; + //number of received data packets private int n=0; protected void onDataPacketReceived(DataPacket dp)throws IOException{ long currentSequenceNumber = dp.getPacketSequenceNumber(); + //check whether to drop this packet n++; if(dropRate>0 && n % dropRate == 0){ @@ -379,6 +382,7 @@ return; } + long currentDataPacketArrivalTime = Util.getCurrentTime(); /*(4).if the seqNo of the current data packet is 16n+1,record the @@ -418,6 +422,11 @@ if(currentSequenceNumber>largestReceivedSeqNumber){ largestReceivedSeqNumber=currentSequenceNumber; } + + //(8) need to send an ACK? Some cc algorithms use this + if(ackInterval>0){ + if(n % ackInterval == 0)processACKEvent(false); + } } /** @@ -438,6 +447,7 @@ receiverLossList.insert(detectedLossSeqNumber); } endpoint.doSend(nAckPacket); + //logger.info("NAK for "+currentSequenceNumber); statistics.incNumberOfNAKSent(); } @@ -513,8 +523,8 @@ if(roundTripTime>0)roundTripTime = (roundTripTime*7 + rtt)/8; else roundTripTime = rtt; roundTripTimeVar = (roundTripTimeVar* 3 + Math.abs(roundTripTimeVar- rtt)) / 4; - ACK_INTERVAL=4*roundTripTime+roundTripTimeVar+Util.getSYNTime(); - NAK_INTERVAL=ACK_INTERVAL; + ackTimerInterval=4*roundTripTime+roundTripTimeVar+Util.getSYNTime(); + nakTimerInterval=ackTimerInterval; statistics.setRTT(roundTripTime, roundTripTimeVar); } } @@ -536,7 +546,7 @@ private volatile long ackSequenceNumber=0; protected void resetEXPTimer(){ - nextEXP=Util.getCurrentTime()+EXP_INTERVAL; + nextEXP=Util.getCurrentTime()+expTimerInterval; expCount=0; } @@ -544,6 +554,10 @@ expCount=0; } + public void setAckInterval(long ackInterval){ + this.ackInterval=ackInterval; + } + protected void onShutdown()throws IOException{ stop(); } Modified: udt-java/trunk/src/main/java/udt/UDTSender.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSender.java 2010-04-29 21:33:20 UTC (rev 31) +++ udt-java/trunk/src/main/java/udt/UDTSender.java 2010-04-30 14:02:45 UTC (rev 32) @@ -246,7 +246,7 @@ long ackNumber=acknowledgement.getAckNumber(); cc.onACK(ackNumber); - statistics.setCongestionWindowSize(cc.getCongestionWindowSize()); + statistics.setCongestionWindowSize((long)cc.getCongestionWindowSize()); //need to remove all sequence numbers up the ack number from the sendBuffer boolean removed=false; for(long s=lastAckSequenceNumber;s<ackNumber;s++){ @@ -274,7 +274,7 @@ for(Integer i: nak.getDecodedLossInfo()){ senderLossList.insert(Long.valueOf(i)); } - session.getCongestionControl().onNAK(nak.getDecodedLossInfo()); + session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); session.getSocket().getReceiver().resetEXPTimer(); statistics.incNumberOfNAKReceived(); statistics.storeParameters(); @@ -306,17 +306,16 @@ /** * sender algorithm */ - MeanValue v=new MeanValue("",true,128); + MeanValue v=new MeanValue("Wait for Ack time: "); public void senderAlgorithm()throws InterruptedException, IOException{ + statistics.addMetric(v); while(!paused){ long iterationStart=Util.getCurrentTime(); //last packet send time? //if the sender's loss list is not empty if (!senderLossList.isEmpty()) { - v.begin(); Long entry=senderLossList.getFirstEntry(); - v.end(); handleResubmit(entry); } @@ -327,7 +326,7 @@ int unAcknowledged=unacknowledged.get(); if(unAcknowledged<session.getCongestionControl().getCongestionWindowSize() - && unAcknowledged<session.getFlowWindowSize()){ + && unAcknowledged<session.getFlowWindowSize()){ //check for application data DataPacket dp=sendQueue.poll(); if(dp!=null){ @@ -342,7 +341,9 @@ if(unAcknowledged>=session.getCongestionControl().getCongestionWindowSize()){ statistics.incNumberOfCCWindowExceededEvents(); } + v.begin(); waitForAck(); + v.end(); } } @@ -455,7 +456,7 @@ */ public void waitForAck()throws InterruptedException{ waitForAckLatch.set(new CountDownLatch(1)); - waitForAckLatch.get().await(1000, TimeUnit.MILLISECONDS); + waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); } Modified: udt-java/trunk/src/main/java/udt/UDTSession.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSession.java 2010-04-29 21:33:20 UTC (rev 31) +++ udt-java/trunk/src/main/java/udt/UDTSession.java 2010-04-30 14:02:45 UTC (rev 32) @@ -34,6 +34,7 @@ import java.net.DatagramPacket; import java.util.concurrent.atomic.AtomicLong; +import java.util.logging.Level; import java.util.logging.Logger; import udt.packets.Destination; @@ -72,7 +73,7 @@ * flow window size, i.e. how many data packets are * in-flight at a single time */ - protected int flowWindowSize=128; + protected int flowWindowSize=4*128; /** * remote UDT entity (address and socket ID) @@ -110,21 +111,23 @@ mySocketID=nextSocketID.incrementAndGet(); this.destination=destination; this.dgPacket=new DatagramPacket(new byte[0],0,destination.getAddress(),destination.getPort()); - //init configurable CC String clazzP=System.getProperty(CC_CLASS,UDTCongestionControl.class.getName()); Object ccObject=null; try{ Class<?>clazz=Class.forName(clazzP); ccObject=clazz.getDeclaredConstructor(UDTSession.class).newInstance(this); }catch(Exception e){ + logger.log(Level.WARNING,"Can't setup congestion control class <"+clazzP+">, using default.",e); ccObject=new UDTCongestionControl(this); } cc=(CongestionControl)ccObject; - System.out.println("using "+cc.getClass().getName()); + logger.info("Using "+cc.getClass().getName()); } + public abstract void received(UDTPacket packet, Destination peer); + public UDTSocket getSocket() { return socket; } Added: udt-java/trunk/src/main/java/udt/cc/SimpleTCP.java =================================================================== --- udt-java/trunk/src/main/java/udt/cc/SimpleTCP.java (rev 0) +++ udt-java/trunk/src/main/java/udt/cc/SimpleTCP.java 2010-04-30 14:02:45 UTC (rev 32) @@ -0,0 +1,36 @@ +package udt.cc; + +import java.util.List; + +import udt.UDTCongestionControl; +import udt.UDTSession; + +/** + * simple TCP CC algorithm from the paper + * "Optimizing UDP-based Protocol Implementations" by Y. Gu and R. Grossmann + */ +public class SimpleTCP extends UDTCongestionControl { + + public SimpleTCP(UDTSession session){ + super(session); + } + + @Override + public void init() { + packetSendingPeriod=0; + congestionWindowSize=2; + setAckInterval(2); + } + + @Override + public void onACK(long ackSeqno) { + congestionWindowSize += 1/congestionWindowSize; + } + + @Override + public void onLoss(List<Integer> lossInfo) { + congestionWindowSize *= 0.5; + } + + +} Property changes on: udt-java/trunk/src/main/java/udt/cc/SimpleTCP.java ___________________________________________________________________ Added: svn:mime-type + text/plain Modified: udt-java/trunk/src/main/java/udt/sender/SenderLossList.java =================================================================== --- udt-java/trunk/src/main/java/udt/sender/SenderLossList.java 2010-04-29 21:33:20 UTC (rev 31) +++ udt-java/trunk/src/main/java/udt/sender/SenderLossList.java 2010-04-30 14:02:45 UTC (rev 32) @@ -48,6 +48,7 @@ } public void insert(Long obj){ + if(obj==null)System.out.println("!!!"); synchronized (backingList) { if(!backingList.contains(obj)){ if(backingList.isEmpty())backingList.add(obj); @@ -62,17 +63,13 @@ } } - public void remove(long seqNo){ - synchronized (backingList) { - backingList.remove(seqNo); - } - } - /** * retrieves the loss list entry with the lowest sequence number */ public Long getFirstEntry(){ - return backingList.poll(); + synchronized(backingList){ + return backingList.poll(); + } } public boolean isEmpty(){ Modified: udt-java/trunk/src/main/java/udt/util/MeanValue.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/MeanValue.java 2010-04-29 21:33:20 UTC (rev 31) +++ udt-java/trunk/src/main/java/udt/util/MeanValue.java 2010-04-30 14:02:45 UTC (rev 32) @@ -42,7 +42,7 @@ public void addValue(double value){ mean=(mean*n+value)/(n+1); n++; - if(verbose && n % nValue == 1){ + if(verbose && n % nValue == 0){ if(msg!=null)System.out.print(msg+" "); System.out.println(getFormattedMean()); } Modified: udt-java/trunk/src/main/java/udt/util/UDTStatistics.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/UDTStatistics.java 2010-04-29 21:33:20 UTC (rev 31) +++ udt-java/trunk/src/main/java/udt/util/UDTStatistics.java 2010-04-30 14:02:45 UTC (rev 32) @@ -35,8 +35,6 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -69,17 +67,10 @@ private volatile double sendPeriod; private volatile long congestionWindowSize; - private MessageDigest digest; - private final List<MeanValue>metrics=new ArrayList<MeanValue>(); public UDTStatistics(String componentDescription){ this.componentDescription=componentDescription; - try{ - digest=MessageDigest.getInstance("MD5"); - }catch(NoSuchAlgorithmException na){ - digest=null; - } } public int getNumberOfSentDataPackets() { @@ -170,14 +161,6 @@ this.congestionWindowSize = congestionWindowSize; } - public void updateReadDataMD5(byte[]data){ - digest.update(data); - } - - public String getDigest(){ - return hexString(digest); - } - public long getPacketArrivalRate(){ return packetArrivalRate; } @@ -268,15 +251,4 @@ } } - public static String hexString(MessageDigest digest){ - byte[] messageDigest = digest.digest(); - StringBuilder hexString = new StringBuilder(); - for (int i=0;i<messageDigest.length;i++) { - String hex = Integer.toHexString(0xFF & messageDigest[i]); - if(hex.length()==1)hexString.append('0'); - hexString.append(hex); - } - return hexString.toString(); - } - } Modified: udt-java/trunk/src/main/java/udt/util/Util.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/Util.java 2010-04-29 21:33:20 UTC (rev 31) +++ udt-java/trunk/src/main/java/udt/util/Util.java 2010-04-30 14:02:45 UTC (rev 32) @@ -38,6 +38,7 @@ import java.io.OutputStream; import java.net.DatagramPacket; import java.net.InetAddress; +import java.security.MessageDigest; import udt.UDPEndPoint; @@ -149,5 +150,16 @@ p.setPort(clientPort); endpoint.sendRaw(p); } + + public static String hexString(MessageDigest digest){ + byte[] messageDigest = digest.digest(); + StringBuilder hexString = new StringBuilder(); + for (int i=0;i<messageDigest.length;i++) { + String hex = Integer.toHexString(0xFF & messageDigest[i]); + if(hex.length()==1)hexString.append('0'); + hexString.append(hex); + } + return hexString.toString(); + } } Modified: udt-java/trunk/src/test/java/udt/TestUDTInputStream.java =================================================================== --- udt-java/trunk/src/test/java/udt/TestUDTInputStream.java 2010-04-29 21:33:20 UTC (rev 31) +++ udt-java/trunk/src/test/java/udt/TestUDTInputStream.java 2010-04-30 14:02:45 UTC (rev 32) @@ -3,6 +3,7 @@ import java.security.MessageDigest; import udt.util.UDTStatistics; +import udt.util.Util; public class TestUDTInputStream extends UDTTestBase{ @@ -18,8 +19,8 @@ is.haveNewData(3, data3); is.noMoreData(); is.setBlocking(false); - readAll(is,8); - assertEquals(digest,stat.getDigest()); + String readMD5=readAll(is,8); + assertEquals(digest,readMD5); } public void test2()throws Exception{ @@ -34,8 +35,8 @@ is.haveNewData(2, data2); is.haveNewData(3, data3); is.noMoreData(); - readAll(is,5*1024*1024); - assertEquals(digest,stat.getDigest()); + String readMD5=readAll(is,5*1024*1024); + assertEquals(digest,readMD5); } public void testInOrder()throws Exception{ @@ -52,8 +53,8 @@ } is.noMoreData(); - readAll(is,1024*999); - assertEquals(digest,stat.getDigest()); + String readMD5 = readAll(is,1024*999); + assertEquals(digest,readMD5); } public void testRandomOrder()throws Exception{ @@ -70,9 +71,9 @@ for(int i : order){ is.haveNewData(i+1, blocks[i]); } - readAll(is,512,true); + String readMD5=readAll(is,512,true); - assertEquals(digest,stat.getDigest()); + assertEquals(digest,readMD5); } //read and discard data from the given input stream @@ -89,7 +90,7 @@ if(c>0)d.update(buf,0,c); } } - return UDTStatistics.hexString(d); + return Util.hexString(d); } } Modified: udt-java/trunk/src/test/java/udt/TestUDTServerSocket.java =================================================================== --- udt-java/trunk/src/test/java/udt/TestUDTServerSocket.java 2010-04-29 21:33:20 UTC (rev 31) +++ udt-java/trunk/src/test/java/udt/TestUDTServerSocket.java 2010-04-30 14:02:45 UTC (rev 32) @@ -6,7 +6,7 @@ import java.util.logging.Level; import java.util.logging.Logger; -import udt.util.UDTStatistics; +import udt.util.Util; public class TestUDTServerSocket extends UDTTestBase{ @@ -115,7 +115,7 @@ } System.out.println("Server thread exiting."); serverRunning=false; - md5_received=UDTStatistics.hexString(md5); + md5_received=Util.hexString(md5); serverSocket.shutDown(); System.out.println(s.getSession().getStatistics()); } Modified: udt-java/trunk/src/test/java/udt/UDTTestBase.java =================================================================== --- udt-java/trunk/src/test/java/udt/UDTTestBase.java 2010-04-29 21:33:20 UTC (rev 31) +++ udt-java/trunk/src/test/java/udt/UDTTestBase.java 2010-04-30 14:02:45 UTC (rev 32) @@ -5,7 +5,7 @@ import java.security.MessageDigest; import java.util.Random; -import udt.util.UDTStatistics; +import udt.util.Util; import junit.framework.TestCase; @@ -60,7 +60,7 @@ } public static String hexString(MessageDigest digest){ - return UDTStatistics.hexString(digest); + return Util.hexString(digest); } Modified: udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-04-29 21:33:20 UTC (rev 31) +++ udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-04-30 14:02:45 UTC (rev 32) @@ -14,6 +14,7 @@ import udt.UDTServerSocket; import udt.UDTSocket; import udt.UDTTestBase; +import udt.util.Util; public class TestUDTLargeData extends UDTTestBase{ @@ -87,7 +88,7 @@ System.out.println("MD5 hash of data received: "+md5_received); System.out.println(client.getStatistics()); - //assertEquals(md5_sent,md5_received); + assertEquals(md5_sent,md5_received); //store stat history to csv file client.getStatistics().writeParameterHistory(File.createTempFile("/udtstats-",".csv")); @@ -106,6 +107,7 @@ Runnable serverProcess=new Runnable(){ public void run(){ try{ + MessageDigest md5=MessageDigest.getInstance("MD5"); long start=System.currentTimeMillis(); UDTSocket s=serverSocket.accept(); assertNotNull(s); @@ -117,12 +119,13 @@ c=is.read(buf); if(c<0)break; else{ + md5.update(buf,0,c); total+=c; } } System.out.println("Server thread exiting, last received bytes: "+c); serverRunning=false; - md5_received=s.getSession().getStatistics().getDigest(); + md5_received=Util.hexString(md5); serverSocket.shutDown(); System.out.println(s.getSession().getStatistics()); } Added: udt-java/trunk/src/test/java/udt/performance/TestUDTLargeDataCC1.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/TestUDTLargeDataCC1.java (rev 0) +++ udt-java/trunk/src/test/java/udt/performance/TestUDTLargeDataCC1.java 2010-04-30 14:02:45 UTC (rev 32) @@ -0,0 +1,33 @@ +package udt.performance; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import udt.UDTReceiver; +import udt.UDTSession; +import udt.cc.SimpleTCP; + +//uses different CC algorithm +public class TestUDTLargeDataCC1 extends TestUDTLargeData{ + + boolean running=false; + + //how many + int num_packets=50; + + //how large is a single packet + int size=1*1024*1024; + + int TIMEOUT=Integer.MAX_VALUE; + + int READ_BUFFERSIZE=1*1024*1024; + + public void test1()throws Exception{ + Logger.getLogger("udt").setLevel(Level.INFO); + UDTReceiver.dropRate=0; + System.setProperty(UDTSession.CC_CLASS, SimpleTCP.class.getName()); + TIMEOUT=Integer.MAX_VALUE; + doTest(); + } + +} Property changes on: udt-java/trunk/src/test/java/udt/performance/TestUDTLargeDataCC1.java ___________________________________________________________________ Added: svn:mime-type + text/plain This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2010-04-30 19:09:31
|
Revision: 33 http://udt-java.svn.sourceforge.net/udt-java/?rev=33&view=rev Author: bschuller Date: 2010-04-30 19:09:25 +0000 (Fri, 30 Apr 2010) Log Message: ----------- bugfix in sender loss list Modified Paths: -------------- udt-java/trunk/src/main/java/udt/UDTReceiver.java udt-java/trunk/src/main/java/udt/UDTSender.java udt-java/trunk/src/main/java/udt/sender/SenderLossList.java udt-java/trunk/src/test/java/udt/TestList.java udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java udt-java/trunk/src/test/java/udt/performance/TestUDTLargeDataCC1.java Modified: udt-java/trunk/src/main/java/udt/UDTReceiver.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-04-30 14:02:45 UTC (rev 32) +++ udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-04-30 19:09:25 UTC (rev 33) @@ -377,10 +377,11 @@ //check whether to drop this packet n++; - if(dropRate>0 && n % dropRate == 0){ - logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); - return; - } + //if(dropRate>0 && n % dropRate == 0){ + //if(n==668){ + // logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); + // return; + //} long currentDataPacketArrivalTime = Util.getCurrentTime(); Modified: udt-java/trunk/src/main/java/udt/UDTSender.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSender.java 2010-04-30 14:02:45 UTC (rev 32) +++ udt-java/trunk/src/main/java/udt/UDTSender.java 2010-04-30 19:09:25 UTC (rev 33) @@ -91,13 +91,13 @@ private final AtomicInteger unacknowledged=new AtomicInteger(0); //for generating data packet sequence numbers - private long nextSequenceNumber=0; + private volatile long currentSequenceNumber=0; //the largest data packet sequence number that has actually been sent out private volatile long largestSentSequenceNumber=-1; //last acknowledge number, initialised to the initial sequence number - private long lastAckSequenceNumber; + private volatile long lastAckSequenceNumber; private volatile boolean started=false; @@ -269,8 +269,6 @@ * @param nak */ protected void onNAKPacketReceived(NegativeAcknowledgement nak){ - waitForAckLatch.get().countDown(); - for(Integer i: nak.getDecodedLossInfo()){ senderLossList.insert(Long.valueOf(i)); } @@ -283,7 +281,6 @@ logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " +"set send period to "+session.getCongestionControl().getSendInterval()); } - return; } @@ -382,7 +379,7 @@ if(pktToRetransmit!=null){ endpoint.doSend(pktToRetransmit); statistics.incNumberOfRetransmittedDataPackets(); - } + } }catch (Exception e) { logger.log(Level.WARNING,"",e); } @@ -404,12 +401,12 @@ * The initial sequence number is "0" */ public long getNextSequenceNumber(){ - nextSequenceNumber++; - return nextSequenceNumber; + currentSequenceNumber++; + return currentSequenceNumber; } public long getCurrentSequenceNumber(){ - return nextSequenceNumber; + return currentSequenceNumber; } /** Modified: udt-java/trunk/src/main/java/udt/sender/SenderLossList.java =================================================================== --- udt-java/trunk/src/main/java/udt/sender/SenderLossList.java 2010-04-30 14:02:45 UTC (rev 32) +++ udt-java/trunk/src/main/java/udt/sender/SenderLossList.java 2010-04-30 19:09:25 UTC (rev 33) @@ -39,7 +39,7 @@ public class SenderLossList { private final LinkedList<Long>backingList; - + /** * create a new sender lost list */ @@ -48,17 +48,15 @@ } public void insert(Long obj){ - if(obj==null)System.out.println("!!!"); synchronized (backingList) { if(!backingList.contains(obj)){ - if(backingList.isEmpty())backingList.add(obj); - else{ - for(int i=0;i<backingList.size();i++){ - if(obj<backingList.getFirst()){ - backingList.add(i,obj); - } + for(int i=0;i<backingList.size();i++){ + if(obj<backingList.getFirst()){ + backingList.add(i,obj); + return; } } + backingList.add(obj); } } } @@ -76,7 +74,13 @@ return backingList.isEmpty(); } + public int size(){ + return backingList.size(); + } + public String toString(){ - return backingList.toString(); + synchronized (backingList) { + return backingList.toString(); + } } } Modified: udt-java/trunk/src/test/java/udt/TestList.java =================================================================== --- udt-java/trunk/src/test/java/udt/TestList.java 2010-04-30 14:02:45 UTC (rev 32) +++ udt-java/trunk/src/test/java/udt/TestList.java 2010-04-30 19:09:25 UTC (rev 33) @@ -85,6 +85,7 @@ l.insert(A); l.insert(B); l.insert(C); + assertEquals(3,l.size()); Long oldest=l.getFirstEntry(); assertEquals(C,oldest); } Modified: udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-04-30 14:02:45 UTC (rev 32) +++ udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-04-30 19:09:25 UTC (rev 33) @@ -21,7 +21,7 @@ boolean running=false; //how many - int num_packets=100; + int num_packets=500; //how large is a single packet int size=1*1024*1024; Modified: udt-java/trunk/src/test/java/udt/performance/TestUDTLargeDataCC1.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/TestUDTLargeDataCC1.java 2010-04-30 14:02:45 UTC (rev 32) +++ udt-java/trunk/src/test/java/udt/performance/TestUDTLargeDataCC1.java 2010-04-30 19:09:25 UTC (rev 33) @@ -13,7 +13,7 @@ boolean running=false; //how many - int num_packets=50; + int num_packets=100; //how large is a single packet int size=1*1024*1024; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2010-05-24 19:15:39
|
Revision: 36 http://udt-java.svn.sourceforge.net/udt-java/?rev=36&view=rev Author: bschuller Date: 2010-05-24 19:15:33 +0000 (Mon, 24 May 2010) Log Message: ----------- Modified Paths: -------------- udt-java/trunk/src/main/java/udt/UDTSender.java udt-java/trunk/src/main/java/udt/packets/DataPacket.java udt-java/trunk/src/main/java/udt/util/Util.java udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java udt-java/trunk/src/test/java/udt/performance/UDPTest.java Modified: udt-java/trunk/src/main/java/udt/UDTSender.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSender.java 2010-05-01 20:49:52 UTC (rev 35) +++ udt-java/trunk/src/main/java/udt/UDTSender.java 2010-05-24 19:15:33 UTC (rev 36) @@ -34,10 +34,10 @@ import java.io.IOException; import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; @@ -124,7 +124,7 @@ statistics=session.getStatistics(); senderLossList=new SenderLossList(); sendBuffer=new ConcurrentHashMap<Long, DataPacket>(session.getFlowWindowSize(),0.75f,2); - sendQueue = new LinkedBlockingQueue<DataPacket>(1000); + sendQueue = new ArrayBlockingQueue<DataPacket>(1000); lastAckSequenceNumber=session.getInitialSequenceNumber(); waitForAckLatch.set(new CountDownLatch(1)); waitForSeqAckLatch.set(new CountDownLatch(1)); @@ -316,11 +316,11 @@ /** * sender algorithm */ + long iterationStart; public void senderAlgorithm()throws InterruptedException, IOException{ while(!paused){ - - long iterationStart=Util.getCurrentTime(); //last packet send time? - + iterationStart=Util.getCurrentTime(); + //if the sender's loss list is not empty if (!senderLossList.isEmpty()) { Long entry=senderLossList.getFirstEntry(); @@ -336,7 +336,7 @@ if(unAcknowledged<session.getCongestionControl().getCongestionWindowSize() && unAcknowledged<session.getFlowWindowSize()){ //check for application data - DataPacket dp=sendQueue.poll(); + DataPacket dp=sendQueue.poll(Util.SYN,TimeUnit.MICROSECONDS); if(dp!=null){ send(dp); largestSentSequenceNumber=dp.getPacketSequenceNumber(); @@ -345,7 +345,7 @@ statistics.incNumberOfMissingDataEvents(); } }else{ - //congestion window full, should we *really* wait for an ack?! + //congestion window full, wait for an ack if(unAcknowledged>=session.getCongestionControl().getCongestionWindowSize()){ statistics.incNumberOfCCWindowExceededEvents(); } @@ -355,7 +355,7 @@ //wait if(largestSentSequenceNumber % 16 !=0){ - double snd=session.getCongestionControl().getSendInterval(); + long snd=(long)session.getCongestionControl().getSendInterval(); long passed=Util.getCurrentTime()-iterationStart; int x=0; while(snd-passed>0){ @@ -376,13 +376,6 @@ * @param entry */ protected void handleResubmit(Long seqNumber){ - //long seqNumber=entry.getSequenceNumber(); - //TODO - //if the current seqNumber is 16n,check the timeOut in the - //loss list and send a message drop request. - //if((seqNumber%16)==0){ - //sendLossList.checkTimeOut(timeToLive); - //} try { //retransmit the packet and remove it from the list DataPacket pktToRetransmit = sendBuffer.get(seqNumber); Modified: udt-java/trunk/src/main/java/udt/packets/DataPacket.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/DataPacket.java 2010-05-01 20:49:52 UTC (rev 35) +++ udt-java/trunk/src/main/java/udt/packets/DataPacket.java 2010-05-24 19:15:33 UTC (rev 36) @@ -152,9 +152,10 @@ */ public byte[] getEncoded(){ byte[] header=getHeader(); - byte[] result=new byte[header.length+data.length]; - System.arraycopy(header, 0, result, 0, header.length); - System.arraycopy(data, 0, result, header.length, data.length); + //header.length is 16 + byte[] result=new byte[16+data.length]; + System.arraycopy(header, 0, result, 0, 16); + System.arraycopy(data, 0, result, 16, data.length); return result; } Modified: udt-java/trunk/src/main/java/udt/util/Util.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/Util.java 2010-05-01 20:49:52 UTC (rev 35) +++ udt-java/trunk/src/main/java/udt/util/Util.java 2010-05-24 19:15:33 UTC (rev 36) @@ -55,11 +55,16 @@ return System.nanoTime()/1000; } + + public static final long SYN=10000; + + public static final double SYN_D=10000.0; + /** * get the SYN time in microseconds. The SYN time is 0.01 seconds = 10000 microseconds * @return */ - public static long getSYNTime(){ + public static final long getSYNTime(){ return 10000; } @@ -122,7 +127,7 @@ * @throws IOException */ public static void copy(InputStream source, OutputStream target, long size, boolean flush)throws IOException{ - byte[]buf=new byte[65536]; + byte[]buf=new byte[8*65536]; int c; long read=0; while(true){ Modified: udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-05-01 20:49:52 UTC (rev 35) +++ udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-05-24 19:15:33 UTC (rev 36) @@ -21,7 +21,7 @@ boolean running=false; //how many - int num_packets=50; + int num_packets=500; //how large is a single packet int size=1*1024*1024; Modified: udt-java/trunk/src/test/java/udt/performance/UDPTest.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/UDPTest.java 2010-05-01 20:49:52 UTC (rev 35) +++ udt-java/trunk/src/test/java/udt/performance/UDPTest.java 2010-05-24 19:15:33 UTC (rev 36) @@ -9,6 +9,7 @@ import junit.framework.TestCase; import udt.UDPEndPoint; +import udt.packets.DataPacket; import udt.util.MeanValue; /** @@ -16,7 +17,7 @@ */ public class UDPTest extends TestCase { - final int num_packets=10*1000; + final int num_packets=10*10*1000; final int packetSize=UDPEndPoint.DATAGRAM_SIZE; public void test1()throws Exception{ @@ -35,8 +36,14 @@ System.out.println("Sending "+num_packets+" data blocks of <"+packetSize+"> bytes"); MeanValue v=new MeanValue("Datagram send time",false); MeanValue v2=new MeanValue("Datagram send interval",false); + MeanValue v3=new MeanValue("Encoding time",false); + for(int i=0;i<num_packets;i++){ - dp.setData(data); + DataPacket p=new DataPacket(); + p.setData(data); + v3.begin(); + dp.setData(p.getEncoded()); + v3.end(); v2.end(); v.begin(); s.send(dp); @@ -52,6 +59,7 @@ System.out.println("Rate "+num_packets+" packets/sec"); System.out.println("Mean send time "+v.getFormattedMean()+" microsec"); System.out.println("Mean send interval "+v2.getFormattedMean()+" microsec"); + System.out.println("Datapacket encoding time "+v3.getFormattedMean()+" microsec"); System.out.println("Server received: "+total); } @@ -92,7 +100,7 @@ long start=System.currentTimeMillis(); while(true){ DatagramPacket dp=handoff.poll(); - total+=dp.getLength(); + if(dp!=null)total+=dp.getLength(); if(total==N)break; } long end=System.currentTimeMillis(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2010-08-30 11:45:39
|
Revision: 42 http://udt-java.svn.sourceforge.net/udt-java/?rev=42&view=rev Author: bschuller Date: 2010-08-30 11:45:32 +0000 (Mon, 30 Aug 2010) Log Message: ----------- use random initial sequence number Modified Paths: -------------- udt-java/trunk/src/main/java/udt/ClientSession.java udt-java/trunk/src/main/java/udt/ServerSession.java udt-java/trunk/src/main/java/udt/UDPEndPoint.java udt-java/trunk/src/main/java/udt/UDTInputStream.java udt-java/trunk/src/main/java/udt/UDTReceiver.java udt-java/trunk/src/main/java/udt/UDTSender.java udt-java/trunk/src/main/java/udt/UDTSocket.java udt-java/trunk/src/main/java/udt/util/MeanValue.java udt-java/trunk/src/main/java/udt/util/SendFile.java udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java Added Paths: ----------- udt-java/trunk/src/main/java/udt/util/SequenceNumber.java Modified: udt-java/trunk/src/main/java/udt/ClientSession.java =================================================================== --- udt-java/trunk/src/main/java/udt/ClientSession.java 2010-06-18 06:35:25 UTC (rev 41) +++ udt-java/trunk/src/main/java/udt/ClientSession.java 2010-08-30 11:45:32 UTC (rev 42) @@ -40,6 +40,7 @@ import udt.packets.ConnectionHandshake; import udt.packets.Destination; import udt.packets.Shutdown; +import udt.util.SequenceNumber; /** * Keep state of a UDT connection. Once established, the @@ -87,6 +88,7 @@ if (getState()!=ready && packet instanceof ConnectionHandshake) { try{ logger.info("Received connection handshake from "+peer); + //TODO validate parameters sent by peer setState(ready); long peerSocketID=((ConnectionHandshake)packet).getSocketID(); destination.setSocketID(peerSocketID); @@ -127,7 +129,9 @@ ConnectionHandshake handshake = new ConnectionHandshake(); handshake.setConnectionType(1); handshake.setSocketType(1); - handshake.setInitialSeqNo(1); + long initialSequenceNo=SequenceNumber.random(); + setInitialSequenceNumber(initialSequenceNo); + handshake.setInitialSeqNo(initialSequenceNo); handshake.setPacketSize(getDatagramSize()); handshake.setSocketID(mySocketID); handshake.setSession(this); Modified: udt-java/trunk/src/main/java/udt/ServerSession.java =================================================================== --- udt-java/trunk/src/main/java/udt/ServerSession.java 2010-06-18 06:35:25 UTC (rev 41) +++ udt-java/trunk/src/main/java/udt/ServerSession.java 2010-08-30 11:45:32 UTC (rev 42) @@ -75,7 +75,7 @@ setState(handshaking); } try{ - sendResponseHandShake(connectionHandshake,peer); + handleHandShake(connectionHandshake,peer); n_handshake++; try{ setState(ready); @@ -144,17 +144,29 @@ return lastPacket; } - protected void sendResponseHandShake(ConnectionHandshake handshake,Destination peer)throws IOException{ + /** + * handle the connection handshake:<br/> + * <ul> + * <li>set initial sequence number</li> + * <li>send response handshake</li> + * </ul> + * @param handshake + * @param peer + * @throws IOException + */ + protected void handleHandShake(ConnectionHandshake handshake,Destination peer)throws IOException{ ConnectionHandshake responseHandshake = new ConnectionHandshake(); //compare the packet size and choose minimun long clientBufferSize=handshake.getPacketSize(); long myBufferSize=getDatagramSize(); long bufferSize=Math.min(clientBufferSize, myBufferSize); + long initialSequenceNumber=handshake.getInitialSeqNo(); + setInitialSequenceNumber(initialSequenceNumber); setDatagramSize((int)bufferSize); responseHandshake.setPacketSize(bufferSize); responseHandshake.setUdtVersion(4); - responseHandshake.setInitialSeqNo(getInitialSequenceNumber()); - responseHandshake.setConnectionType(-1); + responseHandshake.setInitialSeqNo(initialSequenceNumber); + responseHandshake.setConnectionType(1); //tell peer what the socket ID on this side is responseHandshake.setSocketID(mySocketID); responseHandshake.setDestinationID(this.getDestination().getSocketID()); Modified: udt-java/trunk/src/main/java/udt/UDPEndPoint.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDPEndPoint.java 2010-06-18 06:35:25 UTC (rev 41) +++ udt-java/trunk/src/main/java/udt/UDPEndPoint.java 2010-08-30 11:45:32 UTC (rev 42) @@ -162,7 +162,7 @@ try{ doReceive(); }catch(Exception ex){ - ex.printStackTrace(); + logger.log(Level.WARNING,"",ex); } } }; @@ -248,14 +248,16 @@ private long lastDestID=-1; private UDTSession lastSession; - MeanValue v=new MeanValue("",false); + MeanValue v=new MeanValue("receiver processing ",true, 256); protected void doReceive()throws IOException{ while(!stopped){ try{ try{ + v.end(); //will block until a packet is received or timeout has expired dgSocket.receive(dp); + v.begin(); Destination peer=new Destination(dp.getAddress(), dp.getPort()); int l=dp.getLength(); Modified: udt-java/trunk/src/main/java/udt/UDTInputStream.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTInputStream.java 2010-06-18 06:35:25 UTC (rev 41) +++ udt-java/trunk/src/main/java/udt/UDTInputStream.java 2010-08-30 11:45:32 UTC (rev 42) @@ -38,6 +38,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import udt.util.SequenceNumber; import udt.util.UDTStatistics; /** @@ -58,8 +59,9 @@ private final UDTStatistics statistics; - //the highest sequence number read by the application - private volatile long highestSequenceNumber=0; + //the highest sequence number read by the application, initialised + //to the initial sequence number minus one + private volatile long highestSequenceNumber; //set to 'false' by the receiver when it gets a shutdown signal from the peer //see the noMoreData() method @@ -80,6 +82,7 @@ this.statistics=statistics; int capacity=socket!=null? 4*socket.getSession().getFlowWindowSize() : 64 ; appData=new PriorityBlockingQueue<AppData>(capacity); + highestSequenceNumber=SequenceNumber.decrement(socket.getSession().getInitialSequenceNumber()); } /** @@ -177,11 +180,12 @@ } if(currentChunk!=null){ //check if the data is in-order - if(currentChunk.sequenceNumber==highestSequenceNumber+1){ - highestSequenceNumber++; + long cmp=SequenceNumber.compare(currentChunk.sequenceNumber,highestSequenceNumber+1); + if(cmp==0){ + highestSequenceNumber=currentChunk.sequenceNumber; return; } - else if(currentChunk.sequenceNumber<=highestSequenceNumber){ + else if(cmp<0){ //duplicate, drop it currentChunk=null; statistics.incNumberOfDuplicateDataPackets(); @@ -203,7 +207,7 @@ * */ protected boolean haveNewData(long sequenceNumber,byte[]data)throws IOException{ - if(sequenceNumber<=highestSequenceNumber)return true; + if(SequenceNumber.compare(sequenceNumber,highestSequenceNumber)<=0)return true; return appData.offer(new AppData(sequenceNumber,data)); } Modified: udt-java/trunk/src/main/java/udt/UDTReceiver.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-06-18 06:35:25 UTC (rev 41) +++ udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-08-30 11:45:32 UTC (rev 42) @@ -54,6 +54,7 @@ import udt.receiver.ReceiverLossList; import udt.receiver.ReceiverLossListEntry; import udt.util.MeanValue; +import udt.util.SequenceNumber; import udt.util.UDTStatistics; import udt.util.UDTThreadFactory; import udt.util.Util; @@ -417,10 +418,10 @@ /*(6.a).if the number of the current data packet is greater than LSRN+1, put all the sequence numbers between (but excluding) these two values into the receiver's loss list and send them to the sender in an NAK packet*/ - if(currentSequenceNumber>largestReceivedSeqNumber+1){ + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber+1)>0){ sendNAK(currentSequenceNumber); } - else if(currentSequenceNumber<largestReceivedSeqNumber){ + else if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)<0){ /*(6.b).if the sequence number is less than LRSN,remove it from * the receiver's loss list */ @@ -430,7 +431,7 @@ statistics.incNumberOfReceivedDataPackets(); //(7).Update the LRSN - if(currentSequenceNumber>largestReceivedSeqNumber){ + if(SequenceNumber.compare(currentSequenceNumber,largestReceivedSeqNumber)>0){ largestReceivedSeqNumber=currentSequenceNumber; } Modified: udt-java/trunk/src/main/java/udt/UDTSender.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSender.java 2010-06-18 06:35:25 UTC (rev 41) +++ udt-java/trunk/src/main/java/udt/UDTSender.java 2010-08-30 11:45:32 UTC (rev 42) @@ -52,6 +52,7 @@ import udt.sender.SenderLossList; import udt.util.MeanThroughput; import udt.util.MeanValue; +import udt.util.SequenceNumber; import udt.util.UDTStatistics; import udt.util.UDTThreadFactory; import udt.util.Util; @@ -126,6 +127,7 @@ sendBuffer=new ConcurrentHashMap<Long, DataPacket>(session.getFlowWindowSize(),0.75f,2); sendQueue = new ArrayBlockingQueue<DataPacket>(1000); lastAckSequenceNumber=session.getInitialSequenceNumber(); + currentSequenceNumber=session.getInitialSequenceNumber()-1; waitForAckLatch.set(new CountDownLatch(1)); waitForSeqAckLatch.set(new CountDownLatch(1)); storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); @@ -404,7 +406,7 @@ * The initial sequence number is "0" */ public long getNextSequenceNumber(){ - currentSequenceNumber++; + currentSequenceNumber=SequenceNumber.increment(currentSequenceNumber); return currentSequenceNumber; } @@ -426,12 +428,11 @@ } boolean haveAcknowledgementFor(long sequenceNumber){ - return sequenceNumber<=lastAckSequenceNumber; + return SequenceNumber.compare(sequenceNumber,lastAckSequenceNumber)<=0; } boolean isSentOut(long sequenceNumber){ - return largestSentSequenceNumber>=sequenceNumber; - + return SequenceNumber.compare(largestSentSequenceNumber,sequenceNumber)>=0; } boolean haveLostPackets(){ Modified: udt-java/trunk/src/main/java/udt/UDTSocket.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSocket.java 2010-06-18 06:35:25 UTC (rev 41) +++ udt-java/trunk/src/main/java/udt/UDTSocket.java 2010-08-30 11:45:32 UTC (rev 42) @@ -204,7 +204,8 @@ sender.waitForAck(seqNo); } } - sender.pause(); + //TODO need to check if we can pause the sender... + //sender.pause(); } //writes and wait for ack Modified: udt-java/trunk/src/main/java/udt/util/MeanValue.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/MeanValue.java 2010-06-18 06:35:25 UTC (rev 41) +++ udt-java/trunk/src/main/java/udt/util/MeanValue.java 2010-08-30 11:45:32 UTC (rev 42) @@ -4,7 +4,7 @@ import java.util.Locale; /** - * holds a floating mean value + * holds a floating mean timing value (measured in microseconds) */ public class MeanValue { @@ -45,7 +45,7 @@ n++; if(verbose && n % nValue == 0){ if(msg!=null)System.out.println(msg+" "+getFormattedMean()); - else System.out.println(getFormattedMean()); + else System.out.println(name+getFormattedMean()); } } Modified: udt-java/trunk/src/main/java/udt/util/SendFile.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/SendFile.java 2010-06-18 06:35:25 UTC (rev 41) +++ udt-java/trunk/src/main/java/udt/util/SendFile.java 2010-08-30 11:45:32 UTC (rev 42) @@ -129,7 +129,7 @@ public RequestRunner(UDTSocket socket){ this.socket=socket; format.setMaximumFractionDigits(3); - memMapped=true; + memMapped=false;//true; } public void run(){ @@ -188,6 +188,7 @@ private static void copyFile(File file, OutputStream os)throws Exception{ FileChannel c=new RandomAccessFile(file,"r").getChannel(); MappedByteBuffer b=c.map(MapMode.READ_ONLY, 0, file.length()); + b.load(); byte[]buf=new byte[1024*1024]; int len=0; while(true){ Added: udt-java/trunk/src/main/java/udt/util/SequenceNumber.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/SequenceNumber.java (rev 0) +++ udt-java/trunk/src/main/java/udt/util/SequenceNumber.java 2010-08-30 11:45:32 UTC (rev 42) @@ -0,0 +1,73 @@ +package udt.util; + +import java.util.Random; + + +/** + * Handle sequence numbers, taking the range of 0 - (2^31 - 1) into account<br/> + */ + +public class SequenceNumber { + + private final static int maxOffset=0x3FFFFFFF; + + private final static long maxSequenceNo=0x7FFFFFFF; + + + /** + * compare seq1 and seq2. Returns zero, if they are equal, a negative value if seq1 is smaller than + * seq2, and a positive value if seq1 is larger than seq2. + * + * @param seq1 + * @param seq2 + */ + public static long compare(long seq1, long seq2){ + return (Math.abs(seq1 - seq2) < maxOffset) ? (seq1 - seq2) : (seq2 - seq1); + } + + /** + * length from the first to the second sequence number, including both + */ + public static long length(long seq1, long seq2) + {return (seq1 <= seq2) ? (seq2 - seq1 + 1) : (seq2 - seq1 + maxSequenceNo + 2);} + + + /** + * compute the offset from seq2 to seq1 + * @param seq1 + * @param seq2 + */ + public static long seqOffset(long seq1, long seq2){ + if (Math.abs(seq1 - seq2) < maxOffset) + return seq2 - seq1; + + if (seq1 < seq2) + return seq2 - seq1 - maxSequenceNo - 1; + + return seq2 - seq1 + maxSequenceNo + 1; + } + + /** + * increment by one + * @param seq + */ + public static long increment(long seq){ + return (seq == maxSequenceNo) ? 0 : seq + 1; + } + + /** + * decrement by one + * @param seq + */ + public static long decrement(long seq){ + return (seq == 0) ? maxSequenceNo : seq - 1; + } + + /** + * generates a random number between 1 and 0x3FFFFFFF (inclusive) + */ + public static long random(){ + return 1+new Random().nextInt(maxOffset); + } + +} Property changes on: udt-java/trunk/src/main/java/udt/util/SequenceNumber.java ___________________________________________________________________ Added: svn:mime-type + text/plain Modified: udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-06-18 06:35:25 UTC (rev 41) +++ udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-08-30 11:45:32 UTC (rev 42) @@ -21,7 +21,7 @@ boolean running=false; //how many - int num_packets=500; + int num_packets=50; //how large is a single packet int size=1*1024*1024; @@ -40,6 +40,7 @@ private final NumberFormat format=NumberFormat.getNumberInstance(); protected void doTest()throws Exception{ + format.setMaximumFractionDigits(2); if(!running)runServer(); @@ -60,6 +61,7 @@ for(int i=0;i<num_packets;i++){ long block=System.currentTimeMillis(); client.send(data); + client.flush(); digest.update(data); double took=System.currentTimeMillis()-block; double arrival=client.getStatistics().getPacketArrivalRate(); @@ -83,7 +85,7 @@ System.out.println("Rate: "+format.format(mbytes)+" Mbytes/sec "+format.format(mbit)+" Mbit/sec"); System.out.println("Server received: "+total); - assertEquals(N,total); + // assertEquals(N,total); System.out.println("MD5 hash of data sent: "+md5_sent); System.out.println("MD5 hash of data received: "+md5_received); System.out.println(client.getStatistics()); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2010-08-30 21:17:22
|
Revision: 43 http://udt-java.svn.sourceforge.net/udt-java/?rev=43&view=rev Author: bschuller Date: 2010-08-30 21:17:15 +0000 (Mon, 30 Aug 2010) Log Message: ----------- change packet encoding to be compatible with UDT v4 (C++ version); change send/recv file a bit. Does not quite work, but much better :) Modified Paths: -------------- udt-java/trunk/src/main/java/udt/ClientSession.java udt-java/trunk/src/main/java/udt/ServerSession.java udt-java/trunk/src/main/java/udt/UDPEndPoint.java udt-java/trunk/src/main/java/udt/UDTReceiver.java udt-java/trunk/src/main/java/udt/packets/Acknowledgement.java udt-java/trunk/src/main/java/udt/packets/Acknowledgment2.java udt-java/trunk/src/main/java/udt/packets/ConnectionHandshake.java udt-java/trunk/src/main/java/udt/packets/ControlPacket.java udt-java/trunk/src/main/java/udt/packets/DataPacket.java udt-java/trunk/src/main/java/udt/packets/PacketFactory.java udt-java/trunk/src/main/java/udt/packets/PacketUtil.java udt-java/trunk/src/main/java/udt/util/Application.java udt-java/trunk/src/main/java/udt/util/ReceiveFile.java udt-java/trunk/src/main/java/udt/util/SendFile.java udt-java/trunk/src/test/java/udt/TestControlPacket.java udt-java/trunk/src/test/java/udt/TestControlPacketType.java udt-java/trunk/src/test/java/udt/TestPacketFactory.java udt-java/trunk/src/test/java/udt/TestSendFileReceiveFile.java Modified: udt-java/trunk/src/main/java/udt/ClientSession.java =================================================================== --- udt-java/trunk/src/main/java/udt/ClientSession.java 2010-08-30 11:45:32 UTC (rev 42) +++ udt-java/trunk/src/main/java/udt/ClientSession.java 2010-08-30 21:17:15 UTC (rev 43) @@ -135,7 +135,7 @@ handshake.setPacketSize(getDatagramSize()); handshake.setSocketID(mySocketID); handshake.setSession(this); - logger.info("Handshake to "+this.getDestination()); + logger.info("Sending "+handshake); endPoint.doSend(handshake); } Modified: udt-java/trunk/src/main/java/udt/ServerSession.java =================================================================== --- udt-java/trunk/src/main/java/udt/ServerSession.java 2010-08-30 11:45:32 UTC (rev 42) +++ udt-java/trunk/src/main/java/udt/ServerSession.java 2010-08-30 21:17:15 UTC (rev 43) @@ -56,10 +56,10 @@ //last received packet (for testing purposes) private UDTPacket lastPacket; - public ServerSession(DatagramPacket dp,UDPEndPoint endPoint)throws SocketException,UnknownHostException{ + public ServerSession(DatagramPacket dp, UDPEndPoint endPoint)throws SocketException,UnknownHostException{ super("ServerSession localPort="+endPoint.getLocalPort()+" peer="+dp.getAddress()+":"+dp.getPort(),new Destination(dp.getAddress(),dp.getPort())); this.endPoint=endPoint; - logger.info("Created "+toString()+" talking to "+getDestination()); + logger.info("Created "+toString()+" talking to "+dp.getAddress()+":"+dp.getPort()); } int n_handshake=0; @@ -68,14 +68,16 @@ public void received(UDTPacket packet, Destination peer){ lastPacket=packet; if (getState()<=ready && packet instanceof ConnectionHandshake) { - logger.info("Received ConnectionHandshake from "+peer); ConnectionHandshake connectionHandshake=(ConnectionHandshake)packet; destination.setSocketID(connectionHandshake.getSocketID()); + + logger.info("Received "+connectionHandshake); + if(getState()<=handshaking){ setState(handshaking); } try{ - handleHandShake(connectionHandshake,peer); + handleHandShake(connectionHandshake); n_handshake++; try{ setState(ready); @@ -154,7 +156,7 @@ * @param peer * @throws IOException */ - protected void handleHandShake(ConnectionHandshake handshake,Destination peer)throws IOException{ + protected void handleHandShake(ConnectionHandshake handshake)throws IOException{ ConnectionHandshake responseHandshake = new ConnectionHandshake(); //compare the packet size and choose minimun long clientBufferSize=handshake.getPacketSize(); @@ -166,11 +168,13 @@ responseHandshake.setPacketSize(bufferSize); responseHandshake.setUdtVersion(4); responseHandshake.setInitialSeqNo(initialSequenceNumber); - responseHandshake.setConnectionType(1); + responseHandshake.setConnectionType(-1); + responseHandshake.setMaxFlowWndSize(handshake.getMaxFlowWndSize()); //tell peer what the socket ID on this side is responseHandshake.setSocketID(mySocketID); responseHandshake.setDestinationID(this.getDestination().getSocketID()); responseHandshake.setSession(this); + logger.info("Sending reply "+responseHandshake); endPoint.doSend(responseHandshake); } Modified: udt-java/trunk/src/main/java/udt/UDPEndPoint.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDPEndPoint.java 2010-08-30 11:45:32 UTC (rev 42) +++ udt-java/trunk/src/main/java/udt/UDPEndPoint.java 2010-08-30 21:17:15 UTC (rev 43) @@ -50,7 +50,6 @@ import udt.packets.ConnectionHandshake; import udt.packets.Destination; import udt.packets.PacketFactory; -import udt.util.MeanValue; import udt.util.UDTThreadFactory; /** @@ -203,6 +202,7 @@ } public void addSession(Long destinationID,UDTSession session){ + logger.info("Storing session <"+destinationID+">"); sessions.put(destinationID, session); } @@ -248,17 +248,21 @@ private long lastDestID=-1; private UDTSession lastSession; - MeanValue v=new MeanValue("receiver processing ",true, 256); + //MeanValue v=new MeanValue("receiver processing ",true, 256); + private final Object lock=new Object(); + protected void doReceive()throws IOException{ while(!stopped){ try{ try{ - v.end(); + //v.end(); + //will block until a packet is received or timeout has expired dgSocket.receive(dp); - v.begin(); + //v.begin(); + Destination peer=new Destination(dp.getAddress(), dp.getPort()); int l=dp.getLength(); UDTPacket packet=PacketFactory.createPacket(dp.getData(),l); @@ -266,19 +270,21 @@ //handle connection handshake if(packet.isConnectionHandshake()){ - UDTSession session=clientSessions.get(peer); - if(session==null){ - session=new ServerSession(dp,this); - addSession(session.getSocketID(),session); - //TODO need to check peer to avoid duplicate server session - if(serverSocketMode){ - logger.fine("Pooling new request."); - sessionHandoff.put(session); - logger.fine("Request taken for processing."); + synchronized(lock){ + UDTSession session=clientSessions.get(peer); + if(session==null){ + session=new ServerSession(dp,this); + addSession(session.getSocketID(),session); + //TODO need to check peer to avoid duplicate server session + if(serverSocketMode){ + logger.fine("Pooling new request."); + sessionHandoff.put(session); + logger.fine("Request taken for processing."); + } } + peer.setSocketID(((ConnectionHandshake)packet).getSocketID()); + session.received(packet,peer); } - peer.setSocketID(((ConnectionHandshake)packet).getSocketID()); - session.received(packet,peer); } else{ //dispatch to existing session Modified: udt-java/trunk/src/main/java/udt/UDTReceiver.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-08-30 11:45:32 UTC (rev 42) +++ udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-08-30 21:17:15 UTC (rev 43) @@ -500,7 +500,7 @@ private Acknowledgement buildLightAcknowledgement(long ackNumber){ Acknowledgement acknowledgmentPkt = new Acknowledgement(); //the packet sequence number to which all the packets have been received - acknowledgmentPkt.setNexttoPrevPktSeqNO(ackNumber); + acknowledgmentPkt.setAckNumber(ackNumber); //assign this ack a unique increasing ACK sequence number acknowledgmentPkt.setAckSequenceNumber(++ackSequenceNumber); acknowledgmentPkt.setRoundTripTime(roundTripTime); Modified: udt-java/trunk/src/main/java/udt/packets/Acknowledgement.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/Acknowledgement.java 2010-08-30 11:45:32 UTC (rev 42) +++ udt-java/trunk/src/main/java/udt/packets/Acknowledgement.java 2010-08-30 21:17:15 UTC (rev 43) @@ -41,10 +41,13 @@ * receipt of packets */ public class Acknowledgement extends ControlPacket { - + + //the ack sequence number + private long ackSequenceNumber ; + //the packet sequence number to which all the previous packets have been received (excluding) private long ackNumber ; - + //round-trip time in microseconds(RTT) private long roundTripTime; // RTT variance @@ -55,13 +58,14 @@ private long pktArrivalSpeed; //estimated link capacity in number of packets per second private long estimatedLinkCapacity; - + public Acknowledgement(){ this.controlPacketType=ControlPacketType.ACK.ordinal(); } - - public Acknowledgement(byte[] controlInformation){ + + public Acknowledgement(long ackSeqNo, byte[] controlInformation){ this(); + this.ackSequenceNumber=ackSeqNo; decodeControlInformation(controlInformation); } @@ -70,10 +74,25 @@ roundTripTime =PacketUtil.decode(data, 4); roundTripTimeVariance = PacketUtil.decode(data, 8); bufferSize = PacketUtil.decode(data, 12); - pktArrivalSpeed = PacketUtil.decode(data, 16); - estimatedLinkCapacity = PacketUtil.decode(data, 20); + if(data.length>16){ + pktArrivalSpeed = PacketUtil.decode(data, 16); + estimatedLinkCapacity = PacketUtil.decode(data, 20); + } } + @Override + protected long getAdditionalInfo(){ + return ackSequenceNumber; + } + + public long getAckSequenceNumber() { + return ackSequenceNumber; + } + public void setAckSequenceNumber(long ackSequenceNumber) { + this.ackSequenceNumber = ackSequenceNumber; + } + + /** * get the ack number (the number up to which all packets have been received (excluding)) * @return @@ -81,15 +100,15 @@ public long getAckNumber() { return ackNumber; } - + /** * set the ack number (the number up to which all packets have been received (excluding)) - * @param nexttoPrevPktSeqNO + * @param ackNumber */ - public void setNexttoPrevPktSeqNO(long nexttoPrevPktSeqNO) { - ackNumber = nexttoPrevPktSeqNO; + public void setAckNumber(long ackNumber) { + this.ackNumber = ackNumber; } - + /** * get the round trip time (microseconds) * @return @@ -104,7 +123,7 @@ public void setRoundTripTime(long RoundTripTime) { roundTripTime = RoundTripTime; } - + /** * set the variance of the round trip time (in microseconds) * @param RoundTripTime @@ -112,35 +131,35 @@ public void setRoundTripTimeVar(long roundTripTimeVar) { roundTripTimeVariance = roundTripTimeVar; } - + public long getRoundTripTimeVar() { return roundTripTimeVariance; } - + public long getBufferSize() { return bufferSize; } - + public void setBufferSize(long bufferSiZe) { this.bufferSize = bufferSiZe; } - + public long getPacketReceiveRate() { return pktArrivalSpeed; } public void setPacketReceiveRate(long packetReceiveRate) { this.pktArrivalSpeed = packetReceiveRate; } - - + + public long getEstimatedLinkCapacity() { return estimatedLinkCapacity; } - + public void setEstimatedLinkCapacity(long estimatedLinkCapacity) { this.estimatedLinkCapacity = estimatedLinkCapacity; } - + @Override public byte[] encodeControlInformation(){ try { @@ -151,17 +170,17 @@ bos.write(PacketUtil.encode(bufferSize)); bos.write(PacketUtil.encode(pktArrivalSpeed)); bos.write(PacketUtil.encode(estimatedLinkCapacity)); - + return bos.toByteArray(); } catch (Exception e) { // can't happen return null; } - + } - + @Override public boolean equals(Object obj) { if (this == obj) @@ -185,9 +204,9 @@ return false; return true; } - - - - + + + + } Modified: udt-java/trunk/src/main/java/udt/packets/Acknowledgment2.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/Acknowledgment2.java 2010-08-30 11:45:32 UTC (rev 42) +++ udt-java/trunk/src/main/java/udt/packets/Acknowledgment2.java 2010-08-30 21:17:15 UTC (rev 43) @@ -39,28 +39,40 @@ */ public class Acknowledgment2 extends ControlPacket{ - public Acknowledgment2(){ - this.controlPacketType=ControlPacketType.ACK2.ordinal(); - } - - public Acknowledgment2(byte[]controlInformation){ - this(); - decode(controlInformation ); - } - - void decode(byte[]data){ - } - public boolean forSender(){ - return false; - } - - private static final byte[]empty=new byte[0]; - @Override - public byte[] encodeControlInformation(){ - return empty; - } + //the ack sequence number + private long ackSequenceNumber ; + + public Acknowledgment2(){ + this.controlPacketType=ControlPacketType.ACK2.ordinal(); } + public Acknowledgment2(long ackSeqNo,byte[]controlInformation){ + this(); + this.ackSequenceNumber=ackSeqNo; + decode(controlInformation ); + } + public long getAckSequenceNumber() { + return ackSequenceNumber; + } + public void setAckSequenceNumber(long ackSequenceNumber) { + this.ackSequenceNumber = ackSequenceNumber; + } + + void decode(byte[]data){ + } + public boolean forSender(){ + return false; + } + + private static final byte[]empty=new byte[0]; + @Override + public byte[] encodeControlInformation(){ + return empty; + } +} + + + Modified: udt-java/trunk/src/main/java/udt/packets/ConnectionHandshake.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/ConnectionHandshake.java 2010-08-30 11:45:32 UTC (rev 42) +++ udt-java/trunk/src/main/java/udt/packets/ConnectionHandshake.java 2010-08-30 21:17:15 UTC (rev 43) @@ -34,6 +34,8 @@ import java.io.ByteArrayOutputStream; +import udt.UDTSession; + public class ConnectionHandshake extends ControlPacket { private long udtVersion=4; @@ -57,7 +59,6 @@ public ConnectionHandshake(byte[]controlInformation){ this(); - //this.controlInformation=controlInformation; decode(controlInformation); } @@ -172,6 +173,23 @@ } + public String toString(){ + StringBuilder sb=new StringBuilder(); + sb.append("ConnectionHandshake ["); + UDTSession session=getSession(); + if(session!=null){ + sb.append(session.getDestination()); + sb.append(", "); + } + sb.append("mySocketID=").append(socketID); + sb.append(", initialSeqNo=").append(initialSeqNo); + sb.append(", packetSize=").append(packetSize); + sb.append(", maxFlowWndSize=").append(maxFlowWndSize); + sb.append(", destSocketID=").append(destinationID); + sb.append("]"); + return sb.toString(); + } + } Modified: udt-java/trunk/src/main/java/udt/packets/ControlPacket.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/ControlPacket.java 2010-08-30 11:45:32 UTC (rev 42) +++ udt-java/trunk/src/main/java/udt/packets/ControlPacket.java 2010-08-30 21:17:15 UTC (rev 43) @@ -42,9 +42,6 @@ protected int controlPacketType; - //used for ACK and ACK2 - protected long ackSequenceNumber; - protected long messageNumber; protected long timeStamp; @@ -63,14 +60,6 @@ return controlPacketType; } - public long getAckSequenceNumber() { - return ackSequenceNumber; - } - public void setAckSequenceNumber(long ackSequenceNumber) { - this.ackSequenceNumber = ackSequenceNumber; - } - - public long getMessageNumber() { return messageNumber; } @@ -105,8 +94,8 @@ // //sequence number with highest bit set to "0" try{ ByteArrayOutputStream bos=new ByteArrayOutputStream(16); - bos.write(PacketUtil.encodeHighesBitTypeAndSeqNumber(true, controlPacketType, ackSequenceNumber)); - bos.write(PacketUtil.encode(messageNumber)); + bos.write(PacketUtil.encodeControlPacketType(controlPacketType)); + bos.write(PacketUtil.encode(getAdditionalInfo())); bos.write(PacketUtil.encode(timeStamp)); bos.write(PacketUtil.encode(destinationID)); return bos.toByteArray(); @@ -114,6 +103,14 @@ return null; } } + + /** + * this method gets the "additional info" for this type of control packet + */ + protected long getAdditionalInfo(){ + return 0L; + } + /** * this method builds the control information @@ -149,16 +146,10 @@ if (getClass() != obj.getClass()) return false; ControlPacket other = (ControlPacket) obj; - if (ackSequenceNumber != other.ackSequenceNumber) - return false; if (controlPacketType != other.controlPacketType) return false; - //if (!Arrays.equals(controlInformation, other.controlInformation)) - // return false; if (destinationID != other.destinationID) return false; - if (messageNumber != other.messageNumber) - return false; if (timeStamp != other.timeStamp) return false; return true; Modified: udt-java/trunk/src/main/java/udt/packets/DataPacket.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/DataPacket.java 2010-08-30 11:45:32 UTC (rev 42) +++ udt-java/trunk/src/main/java/udt/packets/DataPacket.java 2010-08-30 21:17:15 UTC (rev 43) @@ -136,7 +136,7 @@ //sequence number with highest bit set to "0" try{ ByteArrayOutputStream bos=new ByteArrayOutputStream(16); - bos.write(PacketUtil.encodeSetHighest(false, packetSequenceNumber)); + bos.write(PacketUtil.encode(packetSequenceNumber)); bos.write(PacketUtil.encode(messageNumber)); bos.write(PacketUtil.encode(timeStamp)); bos.write(PacketUtil.encode(destinationID)); Modified: udt-java/trunk/src/main/java/udt/packets/PacketFactory.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/PacketFactory.java 2010-08-30 11:45:32 UTC (rev 42) +++ udt-java/trunk/src/main/java/udt/packets/PacketFactory.java 2010-08-30 21:17:15 UTC (rev 43) @@ -64,8 +64,7 @@ ControlPacket packet=null; int pktType=PacketUtil.decodeType(encodedData, 0); - long ackSeqNo =PacketUtil.decodeAckSeqNr(encodedData, 0); - long msgNr = PacketUtil.decode(encodedData, 4); + long additionalInfo = PacketUtil.decode(encodedData, 4); long timeStamp = PacketUtil.decode(encodedData,8) ; long destID = PacketUtil.decode(encodedData,12); byte[] controlInformation = new byte[length-16]; @@ -81,7 +80,7 @@ } //TYPE 0010:2 else if(ControlPacketType.ACK.ordinal()==pktType){ - packet=new Acknowledgement(controlInformation); + packet=new Acknowledgement(additionalInfo,controlInformation); } //TYPE 0011:3 else if(ControlPacketType.NAK.ordinal()==pktType){ @@ -93,7 +92,7 @@ } //TYPE 0110:6 else if(ControlPacketType.ACK2.ordinal()==pktType){ - packet=new Acknowledgment2(controlInformation); + packet=new Acknowledgment2(additionalInfo,controlInformation); } //TYPE 0111:7 else if(ControlPacketType.MESSAGE_DROP_REQUEST.ordinal()==pktType){ @@ -105,8 +104,6 @@ } if(packet!=null){ - packet.setAckSequenceNumber(ackSeqNo); - packet.setMessageNumber(msgNr); packet.setTimeStamp(timeStamp); packet.setDestinationID(destID); } Modified: udt-java/trunk/src/main/java/udt/packets/PacketUtil.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/PacketUtil.java 2010-08-30 11:45:32 UTC (rev 42) +++ udt-java/trunk/src/main/java/udt/packets/PacketUtil.java 2010-08-30 21:17:15 UTC (rev 43) @@ -57,60 +57,27 @@ return new byte[]{m4,m3,m2,m1}; } - - - public static byte[]encodeSetHighestAndType(boolean highest,int type,long value){ - byte m4; - byte m3; - if(highest){ - m4= (byte) (0x80 | type<<3); - m3= (byte) (0); - } - else{ - m4= (byte) (0x7f & value>>24 ); - m3=(byte)(value>>16); - } + + public static byte[]encodeControlPacketType(int type){ + byte m4=(byte) 0x80; - byte m2=(byte)(value>>8); - byte m1=(byte)(value); - return new byte[]{m4,m3,m2,m1}; + byte m3=(byte)type; + return new byte[]{m4,m3,0,0}; } - public static byte[]encodeHighesBitTypeAndSeqNumber(boolean highestBit,int type, long value){ - byte m4,m3; - if(highestBit){ - m4=(byte) (0x80 | type<<3); - m3=(byte)(0); - } - else{ - m4= (byte) (0); - m3=(byte)(0); - } - byte m2=(byte)(value>>8); - byte m1=(byte)(value); - return new byte[]{m4,m3,m2,m1}; - } - public static long decode(byte[]data, int start){ - long result = (data[start] & 0xFF)<<24 - |(data[start+1] & 0xFF)<<16 - |(data[start+2] & 0xFF)<<8 - |(data[start+3] & 0xFF); + long result = (data[start]&0xFF)<<24 + | (data[start+1]&0xFF)<<16 + | (data[start+2]&0xFF)<<8 + | (data[start+3]&0xFF); return result; } public static int decodeType(byte[]data, int start){ - int result = (data[start]&0x78)>>3; + int result = data[start+1]&0xFF; return result; } - - public static long decodeAckSeqNr(byte[]data, int start){ - long result = (data[start+2] & 0xFF)<<8 - |(data[start+3] & 0xFF); - return result; - } - } Modified: udt-java/trunk/src/main/java/udt/util/Application.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/Application.java 2010-08-30 11:45:32 UTC (rev 42) +++ udt-java/trunk/src/main/java/udt/util/Application.java 2010-08-30 21:17:15 UTC (rev 43) @@ -51,4 +51,23 @@ } } + + + + static long decode(byte[]data, int start){ + long result = (data[start+3] & 0xFF)<<24 + |(data[start+2] & 0xFF)<<16 + |(data[start+1] & 0xFF)<<8 + |(data[start] & 0xFF); + return result; + } + + static byte[]encode(long value){ + byte m4= (byte) (value>>24 ); + byte m3=(byte)(value>>16); + byte m2=(byte)(value>>8); + byte m1=(byte)(value); + return new byte[]{m1,m2,m3,m4}; + } + } Modified: udt-java/trunk/src/main/java/udt/util/ReceiveFile.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/ReceiveFile.java 2010-08-30 11:45:32 UTC (rev 42) +++ udt-java/trunk/src/main/java/udt/util/ReceiveFile.java 2010-08-30 21:17:15 UTC (rev 43) @@ -35,7 +35,6 @@ import java.io.File; import java.io.FileOutputStream; import java.net.InetAddress; -import java.nio.ByteBuffer; import java.text.NumberFormat; import udt.UDTClient; @@ -78,29 +77,29 @@ UDTInputStream in=client.getInputStream(); UDTOutputStream out=client.getOutputStream(); - byte[]readBuf=new byte[1024]; - ByteBuffer bb=ByteBuffer.wrap(readBuf); System.out.println("[ReceiveFile] Requesting file "+remoteFile); //send name file info byte[]fName=remoteFile.getBytes(); - bb.putInt(fName.length+1); - bb.put(fName); - bb.put((byte)0); + out.write(encode(fName.length)); + out.write(fName); - out.write(readBuf, 0, bb.position()); out.flush(); //pause the sender to save some CPU time out.pauseOutput(); //read size info (an 4-byte int) - byte[]sizeInfo=new byte[4]; + byte[]sizeInfo=new byte[8]; - while(in.read(sizeInfo)==0); + int total=0; + while(total<sizeInfo.length){ + int r=in.read(sizeInfo); + if(r<0)break; + total+=r; + } + long size=decode(sizeInfo, 0); - long size=ByteBuffer.wrap(sizeInfo).getInt(); - File file=new File(new String(localFile)); System.out.println("[ReceiveFile] Write to local file <"+file.getAbsolutePath()+">"); FileOutputStream fos=new FileOutputStream(file); Modified: udt-java/trunk/src/main/java/udt/util/SendFile.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/SendFile.java 2010-08-30 11:45:32 UTC (rev 42) +++ udt-java/trunk/src/main/java/udt/util/SendFile.java 2010-08-30 21:17:15 UTC (rev 43) @@ -51,8 +51,8 @@ import udt.UDTReceiver; import udt.UDTServerSocket; import udt.UDTSocket; -import udt.packets.PacketUtil; + /** * helper application for sending a single file via UDT * Intended to be compatible with the C++ version in @@ -69,9 +69,9 @@ public SendFile(int serverPort){ this.serverPort=serverPort; - + } - + @Override public void configure(){ super.configure(); @@ -85,22 +85,23 @@ UDTServerSocket server=new UDTServerSocket(myHost,serverPort); while(true){ UDTSocket socket=server.accept(); + Thread.sleep(1000); threadPool.execute(new RequestRunner(socket)); } }catch(Exception ex){ throw new RuntimeException(ex); } } - + /** * main() method for invoking as a commandline application * @param args * @throws Exception */ public static void main(String[] fullArgs) throws Exception{ - + String[] args=parseOptions(fullArgs); - + int serverPort=65321; try{ serverPort=Integer.parseInt(args[0]); @@ -114,24 +115,24 @@ public static void usage(){ System.out.println("Usage: java -cp ... udt.util.SendFile <server_port> " + - "[--verbose] [--localPort=<port>] [--localIP=<ip>]"); + "[--verbose] [--localPort=<port>] [--localIP=<ip>]"); } public static class RequestRunner implements Runnable{ - + private final static Logger logger=Logger.getLogger(RequestRunner.class.getName()); - + private final UDTSocket socket; - + private final NumberFormat format=NumberFormat.getNumberInstance(); - + private final boolean memMapped; public RequestRunner(UDTSocket socket){ this.socket=socket; format.setMaximumFractionDigits(3); memMapped=false;//true; } - + public void run(){ try{ logger.info("Handling request from "+socket.getSession().getDestination()); @@ -144,8 +145,19 @@ while(in.read(readBuf)==0)Thread.sleep(100); //how many bytes to read for the file name - int length=bb.getInt(); - byte[]fileName=new byte[length-1]; + byte[]len=new byte[4]; + bb.get(len); + if(verbose){ + StringBuilder sb=new StringBuilder(); + for(int i=0;i<len.length;i++){ + sb.append(Integer.toString(len[i])); + sb.append(" "); + } + System.out.println("[SendFile] name length data: "+sb.toString()); + } + long length=decode(len, 0); + if(verbose)System.out.println("[SendFile] name length : "+length); + byte[]fileName=new byte[(int)length]; bb.get(fileName); File file=new File(new String(fileName)); @@ -156,7 +168,10 @@ long size=file.length(); System.out.println("[SendFile] File size: "+size); //send size info - out.write(PacketUtil.encode(size)); + out.write(encode(size)); + out.write(encode(0l)); + out.flush(); + long start=System.currentTimeMillis(); //and send the file if(memMapped){ @@ -183,8 +198,8 @@ } } } - - + + private static void copyFile(File file, OutputStream os)throws Exception{ FileChannel c=new RandomAccessFile(file,"r").getChannel(); MappedByteBuffer b=c.map(MapMode.READ_ONLY, 0, file.length()); @@ -199,5 +214,6 @@ } os.flush(); } - + + } Modified: udt-java/trunk/src/test/java/udt/TestControlPacket.java =================================================================== --- udt-java/trunk/src/test/java/udt/TestControlPacket.java 2010-08-30 11:45:32 UTC (rev 42) +++ udt-java/trunk/src/test/java/udt/TestControlPacket.java 2010-08-30 21:17:15 UTC (rev 43) @@ -8,7 +8,6 @@ public void testSequenceNumber1(){ ControlPacket p=new DummyControlPacket(); - p.setAckSequenceNumber(1); byte[]x=p.getHeader(); byte highest=x[0]; //check highest bit is "1" for ControlPacket Modified: udt-java/trunk/src/test/java/udt/TestControlPacketType.java =================================================================== --- udt-java/trunk/src/test/java/udt/TestControlPacketType.java 2010-08-30 11:45:32 UTC (rev 42) +++ udt-java/trunk/src/test/java/udt/TestControlPacketType.java 2010-08-30 21:17:15 UTC (rev 43) @@ -8,11 +8,9 @@ public void testSequenceNumber1(){ ControlPacket p=new DummyControlPacket(); - p.setAckSequenceNumber(1); byte[]x=p.getHeader(); byte highest=x[0]; //check highest bit is "1" for ControlPacket - assertEquals(128, highest & 0x80); byte lowest=x[3]; assertEquals(1, lowest); Modified: udt-java/trunk/src/test/java/udt/TestPacketFactory.java =================================================================== --- udt-java/trunk/src/test/java/udt/TestPacketFactory.java 2010-08-30 11:45:32 UTC (rev 42) +++ udt-java/trunk/src/test/java/udt/TestPacketFactory.java 2010-08-30 21:17:15 UTC (rev 43) @@ -16,26 +16,27 @@ public class TestPacketFactory extends TestCase { public void testData(){ - byte[]data="sdjfsdjfldskjflds".getBytes(); + String test="sdjfsdjfldskjflds"; + + byte[]data=test.getBytes(); data[0]=(byte)(data[0] & 0x7f); UDTPacket p=PacketFactory.createPacket(data); DataPacket recv=(DataPacket)p; String t=new String(recv.getEncoded()); assertTrue(p instanceof DataPacket); - assertEquals("sdjfsdjfldskjflds",t); + assertEquals(test,t); } public void testConnectionHandshake(){ ConnectionHandshake p1 = new ConnectionHandshake(); - p1.setAckSequenceNumber(1234); p1.setMessageNumber(9876); p1.setTimeStamp(3456); p1.setDestinationID(1); p1.setConnectionType(1); p1.setSocketType(1); - p1.setInitialSeqNo(1); + p1.setInitialSeqNo(321); p1.setPacketSize(128); p1.setMaxFlowWndSize(128); p1.setSocketID(1); @@ -58,7 +59,7 @@ p1.setDestinationID(1); p1.setBufferSize(128); p1.setEstimatedLinkCapacity(16); - p1.setNexttoPrevPktSeqNO(9870); + p1.setAckNumber(9870); p1.setPacketReceiveRate(1000); p1.setRoundTripTime(1000); p1.setRoundTripTimeVar(500); @@ -86,7 +87,6 @@ public void testNegativeAcknowledgement(){ NegativeAcknowledgement p1 = new NegativeAcknowledgement(); - p1.setAckSequenceNumber(1231); p1.setMessageNumber(9872); p1.setTimeStamp(3452); p1.setDestinationID(2); @@ -105,7 +105,6 @@ public void testNegativeAcknowledgement2(){ NegativeAcknowledgement p1 = new NegativeAcknowledgement(); - p1.setAckSequenceNumber(1231); p1.setMessageNumber(9872); p1.setTimeStamp(3452); p1.setDestinationID(2); @@ -130,7 +129,6 @@ public void testNegativeAcknowledgement3(){ NegativeAcknowledgement p1 = new NegativeAcknowledgement(); - p1.setAckSequenceNumber(1231); p1.setMessageNumber(9872); p1.setTimeStamp(3452); p1.setDestinationID(2); @@ -148,7 +146,6 @@ public void testShutdown(){ Shutdown p1 = new Shutdown(); - p1.setAckSequenceNumber(1233); p1.setMessageNumber(9874); p1.setTimeStamp(3453); p1.setDestinationID(3); @@ -165,7 +162,6 @@ public void testMessageDropRequest(){ MessageDropRequest p1=new MessageDropRequest(); - p1.setAckSequenceNumber(1234); p1.setMessageNumber(9876); p1.setTimeStamp(3456); p1.setDestinationID(4); Modified: udt-java/trunk/src/test/java/udt/TestSendFileReceiveFile.java =================================================================== --- udt-java/trunk/src/test/java/udt/TestSendFileReceiveFile.java 2010-08-30 11:45:32 UTC (rev 42) +++ udt-java/trunk/src/test/java/udt/TestSendFileReceiveFile.java 2010-08-30 21:17:15 UTC (rev 43) @@ -17,8 +17,8 @@ Thread.sleep(500); }while(!serverStarted); - //File f=new File("src/test/java/datafile"); - File f=new File("/tmp/100MB"); + File f=new File("src/test/java/datafile"); + //File f=new File("/tmp/100MB"); File tmp=File.createTempFile("udtest-", null); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2010-09-13 18:55:14
|
Revision: 48 http://udt-java.svn.sourceforge.net/udt-java/?rev=48&view=rev Author: bschuller Date: 2010-09-13 18:55:07 +0000 (Mon, 13 Sep 2010) Log Message: ----------- some refactoring Modified Paths: -------------- udt-java/trunk/src/main/java/udt/UDTPacket.java udt-java/trunk/src/main/java/udt/UDTReceiver.java udt-java/trunk/src/main/java/udt/packets/ControlPacket.java udt-java/trunk/src/main/java/udt/packets/DataPacket.java Added Paths: ----------- udt-java/trunk/src/test/java/udt/packets/ udt-java/trunk/src/test/java/udt/packets/DummyControlPacket.java udt-java/trunk/src/test/java/udt/packets/TestControlPacketType.java udt-java/trunk/src/test/java/udt/packets/TestDataPacket.java udt-java/trunk/src/test/java/udt/packets/TestPacketFactory.java Removed Paths: ------------- udt-java/trunk/src/test/java/udt/DummyControlPacket.java udt-java/trunk/src/test/java/udt/TestControlPacketType.java udt-java/trunk/src/test/java/udt/TestDataPacket.java udt-java/trunk/src/test/java/udt/TestPacketFactory.java Modified: udt-java/trunk/src/main/java/udt/UDTPacket.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTPacket.java 2010-09-01 13:58:45 UTC (rev 47) +++ udt-java/trunk/src/main/java/udt/UDTPacket.java 2010-09-13 18:55:07 UTC (rev 48) @@ -36,27 +36,21 @@ public long getMessageNumber(); + public void setMessageNumber(long messageNumber) ; - public void setTimeStamp(long timeStamp); + public long getTimeStamp(); - public void setDestinationID(long destinationID); + public long getDestinationID(); public boolean isControlPacket(); public int getControlPacketType(); - - /** - * header - * @return - */ - public byte[] getHeader(); - public byte[] getEncoded(); /** Modified: udt-java/trunk/src/main/java/udt/UDTReceiver.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-09-01 13:58:45 UTC (rev 47) +++ udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-09-13 18:55:07 UTC (rev 48) @@ -387,12 +387,12 @@ long currentSequenceNumber = dp.getPacketSequenceNumber(); //check whether to drop this packet - n++; +// n++; //if(dropRate>0 && n % dropRate == 0){ - //if(n==668){ - // logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); - // return; - //} +// if(n==666){ +// logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); +// return; +// } long currentDataPacketArrivalTime = Util.getCurrentTime(); Modified: udt-java/trunk/src/main/java/udt/packets/ControlPacket.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/ControlPacket.java 2010-09-01 13:58:45 UTC (rev 47) +++ udt-java/trunk/src/main/java/udt/packets/ControlPacket.java 2010-09-13 18:55:07 UTC (rev 48) @@ -32,9 +32,6 @@ package udt.packets; -import java.io.ByteArrayOutputStream; -import java.io.IOException; - import udt.UDTPacket; import udt.UDTSession; @@ -89,19 +86,13 @@ * return the header according to specification p.5 * @return */ - //TODO order?!?!? - public byte[] getHeader(){ -// //sequence number with highest bit set to "0" - try{ - ByteArrayOutputStream bos=new ByteArrayOutputStream(16); - bos.write(PacketUtil.encodeControlPacketType(controlPacketType)); - bos.write(PacketUtil.encode(getAdditionalInfo())); - bos.write(PacketUtil.encode(timeStamp)); - bos.write(PacketUtil.encode(destinationID)); - return bos.toByteArray(); - }catch(IOException ioe){/*can't happen*/ - return null; - } + byte[] getHeader(){ + byte[]res=new byte[16]; + System.arraycopy(PacketUtil.encodeControlPacketType(controlPacketType), 0, res, 0, 4); + System.arraycopy(PacketUtil.encode(getAdditionalInfo()), 0, res, 4, 4); + System.arraycopy(PacketUtil.encode(timeStamp), 0, res, 8, 4); + System.arraycopy(PacketUtil.encode(destinationID), 0, res, 12, 4); + return res; } /** Modified: udt-java/trunk/src/main/java/udt/packets/DataPacket.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/DataPacket.java 2010-09-01 13:58:45 UTC (rev 47) +++ udt-java/trunk/src/main/java/udt/packets/DataPacket.java 2010-09-13 18:55:07 UTC (rev 48) @@ -32,9 +32,6 @@ package udt.packets; -import java.io.ByteArrayOutputStream; -import java.io.IOException; - import udt.UDTPacket; import udt.UDTSession; @@ -115,8 +112,6 @@ return this.timeStamp; } - - public void setDestinationID(long destinationID) { this.destinationID=destinationID; } @@ -125,36 +120,16 @@ this.timeStamp=timeStamp; } - - /** - * return the header according to specification p.5 - * @return - */ - //TODO order? - public byte[] getHeader(){ - //sequence number with highest bit set to "0" - try{ - ByteArrayOutputStream bos=new ByteArrayOutputStream(16); - bos.write(PacketUtil.encode(packetSequenceNumber)); - bos.write(PacketUtil.encode(messageNumber)); - bos.write(PacketUtil.encode(timeStamp)); - bos.write(PacketUtil.encode(destinationID)); - return bos.toByteArray(); - - }catch(IOException ioe){/*can't happen*/ - return null; - } - } - - /** * complete header+data packet for transmission */ public byte[] getEncoded(){ - byte[] header=getHeader(); //header.length is 16 byte[] result=new byte[16+data.length]; - System.arraycopy(header, 0, result, 0, 16); + System.arraycopy(PacketUtil.encode(packetSequenceNumber), 0, result, 0, 4); + System.arraycopy(PacketUtil.encode(messageNumber), 0, result, 4, 4); + System.arraycopy(PacketUtil.encode(timeStamp), 0, result, 8, 4); + System.arraycopy(PacketUtil.encode(destinationID), 0, result, 12, 4); System.arraycopy(data, 0, result, 16, data.length); return result; } Deleted: udt-java/trunk/src/test/java/udt/DummyControlPacket.java =================================================================== --- udt-java/trunk/src/test/java/udt/DummyControlPacket.java 2010-09-01 13:58:45 UTC (rev 47) +++ udt-java/trunk/src/test/java/udt/DummyControlPacket.java 2010-09-13 18:55:07 UTC (rev 48) @@ -1,16 +0,0 @@ -package udt; - -import udt.packets.ControlPacket; - -public class DummyControlPacket extends ControlPacket{ - - public DummyControlPacket(){ - - } - - @Override - public byte[]encodeControlInformation(){ - //TODO Auto-generate method sub - return null; - } -} \ No newline at end of file Deleted: udt-java/trunk/src/test/java/udt/TestControlPacketType.java =================================================================== --- udt-java/trunk/src/test/java/udt/TestControlPacketType.java 2010-09-01 13:58:45 UTC (rev 47) +++ udt-java/trunk/src/test/java/udt/TestControlPacketType.java 2010-09-13 18:55:07 UTC (rev 48) @@ -1,34 +0,0 @@ -package udt; - -import udt.packets.ControlPacket; -import udt.packets.ControlPacket.ControlPacketType; -import junit.framework.TestCase; - -public class TestControlPacketType extends TestCase { - - public void testSequenceNumber1(){ - ControlPacket p=new DummyControlPacket(); - byte[]x=p.getHeader(); - byte highest=x[0]; - assertEquals(128, highest & 0x80); - } - - public void testControlPacketTypes(){ - ControlPacketType t=ControlPacketType.CONNECTION_HANDSHAKE; - assertEquals(0,t.ordinal()); - t=ControlPacketType.KEEP_ALIVE; - assertEquals(1,t.ordinal()); - t=ControlPacketType.ACK; - assertEquals(2,t.ordinal()); - t=ControlPacketType.NAK; - assertEquals(3,t.ordinal()); - t=ControlPacketType.SHUTDOWN; - assertEquals(5,t.ordinal()); - t=ControlPacketType.ACK2; - assertEquals(6,t.ordinal()); - t=ControlPacketType.MESSAGE_DROP_REQUEST; - assertEquals(7,t.ordinal()); - t=ControlPacketType.USER_DEFINED; - assertEquals(15,t.ordinal()); - } -} Deleted: udt-java/trunk/src/test/java/udt/TestDataPacket.java =================================================================== --- udt-java/trunk/src/test/java/udt/TestDataPacket.java 2010-09-01 13:58:45 UTC (rev 47) +++ udt-java/trunk/src/test/java/udt/TestDataPacket.java 2010-09-13 18:55:07 UTC (rev 48) @@ -1,97 +0,0 @@ -package udt; - -import junit.framework.TestCase; -import udt.packets.DataPacket; - -public class TestDataPacket extends TestCase { - - public void testSequenceNumber1(){ - DataPacket p=new DataPacket(); - p.setPacketSequenceNumber(1); - byte[]x=p.getHeader(); - byte highest=x[0]; - //check highest bit is "0" for DataPacket - assertEquals(0, highest & 128); - byte lowest=x[3]; - assertEquals(1, lowest); - } - - public void testEncoded(){ - DataPacket p=new DataPacket(); - p.setPacketSequenceNumber(1); - byte[] data="test".getBytes(); - p.setData(data); - byte[]encoded=p.getEncoded(); - int headerLength=p.getHeader().length; - assertEquals(data.length+headerLength,encoded.length); - byte[]encData=new byte[data.length]; - System.arraycopy(encoded, headerLength, encData, 0, data.length); - String s=new String(encData); - assertEquals("test", s); - System.out.println("String s = " + s); - } - - - public void testDecode1(){ - - DataPacket testPacket1=new DataPacket(); - testPacket1.setPacketSequenceNumber(127); - testPacket1.setDestinationID(1); - byte[] data1="Hallo".getBytes(); - testPacket1.setData(data1); - - //get the encoded data - byte[]encodedData=testPacket1.getEncoded(); - - int headerLength=testPacket1.getHeader().length; - assertEquals(data1.length+headerLength,encodedData.length); - - byte[]payload=new byte[data1.length]; - System.arraycopy(encodedData, headerLength, payload, 0, data1.length); - String s1=new String(payload); - assertEquals("Hallo", s1); - - System.out.println("String s1 = " + s1); - System.out.println("tesPacket1Length = "+ testPacket1.getLength()); - System.out.println("sequenceNumber1 = " + testPacket1.getPacketSequenceNumber()); - System.out.println("messageNumber 1= " + testPacket1.getMessageNumber()); - System.out.println("timeStamp1 = " + testPacket1.getTimeStamp()); - System.out.println("destinationID1 = " + testPacket1.getDestinationID()); - System.out.println("data1 = " + new String(testPacket1.getData())); - - - //create a new DataPacket from the encoded data - DataPacket testPacket2=new DataPacket(encodedData); - // and test - System.out.println("tesPacket2Length = "+ testPacket2.getLength()); - System.out.println("sequenceNumber2 = " + testPacket2.getPacketSequenceNumber()); - System.out.println("messageNumber2 = " + testPacket2.getMessageNumber()); - System.out.println("timeStamp2 = " + testPacket2.getTimeStamp()); - System.out.println("destinationID1 = " + testPacket1.getDestinationID()); - System.out.println("data2 = " + new String(testPacket2.getData())); - - assertEquals(127,testPacket2.getPacketSequenceNumber()); - - - } - - public void testEncodeDecode1(){ - DataPacket dp=new DataPacket(); - dp.setPacketSequenceNumber(127); - dp.setMessageNumber(268435457); - dp.setTimeStamp(128); - dp.setDestinationID(255); - dp.setData("test".getBytes()); - - byte[]encodedData1=dp.getEncoded(); - - DataPacket dp2=new DataPacket(encodedData1); - assertEquals(127,dp2.getPacketSequenceNumber()); - assertEquals(268435457,dp2.getMessageNumber()); - assertEquals(128,dp2.getTimeStamp()); - assertEquals(255,dp2.getDestinationID()); - assertEquals("test", new String(dp2.getData())); - } - - -} Deleted: udt-java/trunk/src/test/java/udt/TestPacketFactory.java =================================================================== --- udt-java/trunk/src/test/java/udt/TestPacketFactory.java 2010-09-01 13:58:45 UTC (rev 47) +++ udt-java/trunk/src/test/java/udt/TestPacketFactory.java 2010-09-13 18:55:07 UTC (rev 48) @@ -1,181 +0,0 @@ -package udt; - -import java.util.ArrayList; -import java.util.List; - -import junit.framework.TestCase; -import udt.packets.Acknowledgement; -import udt.packets.Acknowledgment2; -import udt.packets.ConnectionHandshake; -import udt.packets.DataPacket; -import udt.packets.MessageDropRequest; -import udt.packets.NegativeAcknowledgement; -import udt.packets.PacketFactory; -import udt.packets.Shutdown; - -public class TestPacketFactory extends TestCase { - - public void testData(){ - String test="sdjfsdjfldskjflds"; - - byte[]data=test.getBytes(); - data[0]=(byte)(data[0] & 0x7f); - UDTPacket p=PacketFactory.createPacket(data); - DataPacket recv=(DataPacket)p; - String t=new String(recv.getEncoded()); - assertTrue(p instanceof DataPacket); - assertEquals(test,t); - } - - - public void testConnectionHandshake(){ - ConnectionHandshake p1 = new ConnectionHandshake(); - p1.setMessageNumber(9876); - p1.setTimeStamp(3456); - p1.setDestinationID(1); - - p1.setConnectionType(1); - p1.setSocketType(1); - p1.setInitialSeqNo(321); - p1.setPacketSize(128); - p1.setMaxFlowWndSize(128); - p1.setSocketID(1); - p1.setUdtVersion(4); - - - byte[]p1_data=p1.getEncoded(); - - UDTPacket p=PacketFactory.createPacket(p1_data); - ConnectionHandshake p2=(ConnectionHandshake)p; - assertEquals(p1,p2); - - } - - public void testAcknowledgement(){ - Acknowledgement p1 = new Acknowledgement(); - p1.setAckSequenceNumber(1234); - p1.setMessageNumber(9876); - p1.setTimeStamp(3456); - p1.setDestinationID(1); - p1.setBufferSize(128); - p1.setEstimatedLinkCapacity(16); - p1.setAckNumber(9870); - p1.setPacketReceiveRate(1000); - p1.setRoundTripTime(1000); - p1.setRoundTripTimeVar(500); - - byte[]p1_data=p1.getEncoded(); - UDTPacket p=PacketFactory.createPacket(p1_data); - Acknowledgement p2=(Acknowledgement)p; - assertEquals(p1,p2); - } - - public void testAcknowledgementOfAcknowledgement(){ - Acknowledgment2 p1 = new Acknowledgment2(); - p1.setAckSequenceNumber(1230); - p1.setMessageNumber(9871); - p1.setTimeStamp(3451); - p1.setDestinationID(1); - - byte[]p1_data=p1.getEncoded(); - UDTPacket p=PacketFactory.createPacket(p1_data); - Acknowledgment2 p2=(Acknowledgment2)p; - assertEquals(p1,p2); - - - } - - public void testNegativeAcknowledgement(){ - NegativeAcknowledgement p1 = new NegativeAcknowledgement(); - p1.setMessageNumber(9872); - p1.setTimeStamp(3452); - p1.setDestinationID(2); - p1.addLossInfo(5); - p1.addLossInfo(6); - p1.addLossInfo(7, 10); - byte[]p1_data=p1.getEncoded(); - - UDTPacket p=PacketFactory.createPacket(p1_data); - NegativeAcknowledgement p2=(NegativeAcknowledgement)p; - assertEquals(p1,p2); - - assertEquals((Integer)5, (Integer)p2.getDecodedLossInfo().get(0)); - assertEquals(6, p2.getDecodedLossInfo().size()); - } - - public void testNegativeAcknowledgement2(){ - NegativeAcknowledgement p1 = new NegativeAcknowledgement(); - p1.setMessageNumber(9872); - p1.setTimeStamp(3452); - p1.setDestinationID(2); - List<Long>loss=new ArrayList<Long>(); - loss.add(5l); - loss.add(6l); - loss.add(7l); - loss.add(8l); - loss.add(9l); - loss.add(11l); - - p1.addLossInfo(loss); - byte[]p1_data=p1.getEncoded(); - - UDTPacket p=PacketFactory.createPacket(p1_data); - NegativeAcknowledgement p2=(NegativeAcknowledgement)p; - assertEquals(p1,p2); - - assertEquals((Integer)5, (Integer)p2.getDecodedLossInfo().get(0)); - assertEquals(6, p2.getDecodedLossInfo().size()); - } - - public void testNegativeAcknowledgement3(){ - NegativeAcknowledgement p1 = new NegativeAcknowledgement(); - p1.setMessageNumber(9872); - p1.setTimeStamp(3452); - p1.setDestinationID(2); - p1.addLossInfo(5); - p1.addLossInfo(6); - p1.addLossInfo(147, 226); - byte[]p1_data=p1.getEncoded(); - - UDTPacket p=PacketFactory.createPacket(p1_data); - NegativeAcknowledgement p2=(NegativeAcknowledgement)p; - assertEquals(p1,p2); - - - } - - public void testShutdown(){ - Shutdown p1 = new Shutdown(); - p1.setMessageNumber(9874); - p1.setTimeStamp(3453); - p1.setDestinationID(3); - - - byte[]p1_data=p1.getEncoded(); - - UDTPacket p=PacketFactory.createPacket(p1_data); - Shutdown p2=(Shutdown)p; - assertEquals(p1,p2); - } - - - - public void testMessageDropRequest(){ - MessageDropRequest p1=new MessageDropRequest(); - p1.setMessageNumber(9876); - p1.setTimeStamp(3456); - p1.setDestinationID(4); - - p1.setMsgFirstSeqNo(2); - p1.setMsgLastSeqNo(3); - - - byte[]p1_data=p1.getEncoded(); - - UDTPacket p=PacketFactory.createPacket(p1_data); - assertTrue(p instanceof MessageDropRequest); - MessageDropRequest p2=(MessageDropRequest)p; - assertEquals(p1,p2); - } - -} Copied: udt-java/trunk/src/test/java/udt/packets/DummyControlPacket.java (from rev 41, udt-java/trunk/src/test/java/udt/DummyControlPacket.java) =================================================================== --- udt-java/trunk/src/test/java/udt/packets/DummyControlPacket.java (rev 0) +++ udt-java/trunk/src/test/java/udt/packets/DummyControlPacket.java 2010-09-13 18:55:07 UTC (rev 48) @@ -0,0 +1,16 @@ +package udt.packets; + +import udt.packets.ControlPacket; + +public class DummyControlPacket extends ControlPacket{ + + public DummyControlPacket(){ + + } + + @Override + public byte[]encodeControlInformation(){ + //TODO Auto-generate method sub + return null; + } +} \ No newline at end of file Copied: udt-java/trunk/src/test/java/udt/packets/TestControlPacketType.java (from rev 46, udt-java/trunk/src/test/java/udt/TestControlPacketType.java) =================================================================== --- udt-java/trunk/src/test/java/udt/packets/TestControlPacketType.java (rev 0) +++ udt-java/trunk/src/test/java/udt/packets/TestControlPacketType.java 2010-09-13 18:55:07 UTC (rev 48) @@ -0,0 +1,34 @@ +package udt.packets; + +import udt.packets.ControlPacket; +import udt.packets.ControlPacket.ControlPacketType; +import junit.framework.TestCase; + +public class TestControlPacketType extends TestCase { + + public void testSequenceNumber1(){ + ControlPacket p=new DummyControlPacket(); + byte[]x=p.getHeader(); + byte highest=x[0]; + assertEquals(128, highest & 0x80); + } + + public void testControlPacketTypes(){ + ControlPacketType t=ControlPacketType.CONNECTION_HANDSHAKE; + assertEquals(0,t.ordinal()); + t=ControlPacketType.KEEP_ALIVE; + assertEquals(1,t.ordinal()); + t=ControlPacketType.ACK; + assertEquals(2,t.ordinal()); + t=ControlPacketType.NAK; + assertEquals(3,t.ordinal()); + t=ControlPacketType.SHUTDOWN; + assertEquals(5,t.ordinal()); + t=ControlPacketType.ACK2; + assertEquals(6,t.ordinal()); + t=ControlPacketType.MESSAGE_DROP_REQUEST; + assertEquals(7,t.ordinal()); + t=ControlPacketType.USER_DEFINED; + assertEquals(15,t.ordinal()); + } +} Copied: udt-java/trunk/src/test/java/udt/packets/TestDataPacket.java (from rev 41, udt-java/trunk/src/test/java/udt/TestDataPacket.java) =================================================================== --- udt-java/trunk/src/test/java/udt/packets/TestDataPacket.java (rev 0) +++ udt-java/trunk/src/test/java/udt/packets/TestDataPacket.java 2010-09-13 18:55:07 UTC (rev 48) @@ -0,0 +1,96 @@ +package udt.packets; + +import junit.framework.TestCase; +import udt.packets.DataPacket; + +public class TestDataPacket extends TestCase { + + public void testSequenceNumber1(){ + DataPacket p=new DataPacket(); + p.setPacketSequenceNumber(1); + p.setData(new byte[0]); + byte[]x=p.getEncoded(); + byte highest=x[0]; + //check highest bit is "0" for DataPacket + assertEquals(0, highest & 128); + byte lowest=x[3]; + assertEquals(1, lowest); + } + + public void testEncoded(){ + DataPacket p=new DataPacket(); + p.setPacketSequenceNumber(1); + byte[] data="test".getBytes(); + p.setData(data); + byte[]encoded=p.getEncoded(); + byte[]encData=new byte[data.length]; + System.arraycopy(encoded, 16, encData, 0, data.length); + String s=new String(encData); + assertEquals("test", s); + System.out.println("String s = " + s); + } + + + public void testDecode1(){ + + DataPacket testPacket1=new DataPacket(); + testPacket1.setPacketSequenceNumber(127); + testPacket1.setDestinationID(1); + byte[] data1="Hallo".getBytes(); + testPacket1.setData(data1); + + //get the encoded data + byte[]encodedData=testPacket1.getEncoded(); + + int headerLength=16; + assertEquals(data1.length+headerLength,encodedData.length); + + byte[]payload=new byte[data1.length]; + System.arraycopy(encodedData, headerLength, payload, 0, data1.length); + String s1=new String(payload); + assertEquals("Hallo", s1); + + System.out.println("String s1 = " + s1); + System.out.println("tesPacket1Length = "+ testPacket1.getLength()); + System.out.println("sequenceNumber1 = " + testPacket1.getPacketSequenceNumber()); + System.out.println("messageNumber 1= " + testPacket1.getMessageNumber()); + System.out.println("timeStamp1 = " + testPacket1.getTimeStamp()); + System.out.println("destinationID1 = " + testPacket1.getDestinationID()); + System.out.println("data1 = " + new String(testPacket1.getData())); + + + //create a new DataPacket from the encoded data + DataPacket testPacket2=new DataPacket(encodedData); + // and test + System.out.println("tesPacket2Length = "+ testPacket2.getLength()); + System.out.println("sequenceNumber2 = " + testPacket2.getPacketSequenceNumber()); + System.out.println("messageNumber2 = " + testPacket2.getMessageNumber()); + System.out.println("timeStamp2 = " + testPacket2.getTimeStamp()); + System.out.println("destinationID1 = " + testPacket1.getDestinationID()); + System.out.println("data2 = " + new String(testPacket2.getData())); + + assertEquals(127,testPacket2.getPacketSequenceNumber()); + + + } + + public void testEncodeDecode1(){ + DataPacket dp=new DataPacket(); + dp.setPacketSequenceNumber(127); + dp.setMessageNumber(268435457); + dp.setTimeStamp(128); + dp.setDestinationID(255); + dp.setData("test".getBytes()); + + byte[]encodedData1=dp.getEncoded(); + + DataPacket dp2=new DataPacket(encodedData1); + assertEquals(127,dp2.getPacketSequenceNumber()); + assertEquals(268435457,dp2.getMessageNumber()); + assertEquals(128,dp2.getTimeStamp()); + assertEquals(255,dp2.getDestinationID()); + assertEquals("test", new String(dp2.getData())); + } + + +} Copied: udt-java/trunk/src/test/java/udt/packets/TestPacketFactory.java (from rev 43, udt-java/trunk/src/test/java/udt/TestPacketFactory.java) =================================================================== --- udt-java/trunk/src/test/java/udt/packets/TestPacketFactory.java (rev 0) +++ udt-java/trunk/src/test/java/udt/packets/TestPacketFactory.java 2010-09-13 18:55:07 UTC (rev 48) @@ -0,0 +1,182 @@ +package udt.packets; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; +import udt.UDTPacket; +import udt.packets.Acknowledgement; +import udt.packets.Acknowledgment2; +import udt.packets.ConnectionHandshake; +import udt.packets.DataPacket; +import udt.packets.MessageDropRequest; +import udt.packets.NegativeAcknowledgement; +import udt.packets.PacketFactory; +import udt.packets.Shutdown; + +public class TestPacketFactory extends TestCase { + + public void testData(){ + String test="sdjfsdjfldskjflds"; + + byte[]data=test.getBytes(); + data[0]=(byte)(data[0] & 0x7f); + UDTPacket p=PacketFactory.createPacket(data); + DataPacket recv=(DataPacket)p; + String t=new String(recv.getEncoded()); + assertTrue(p instanceof DataPacket); + assertEquals(test,t); + } + + + public void testConnectionHandshake(){ + ConnectionHandshake p1 = new ConnectionHandshake(); + p1.setMessageNumber(9876); + p1.setTimeStamp(3456); + p1.setDestinationID(1); + + p1.setConnectionType(1); + p1.setSocketType(1); + p1.setInitialSeqNo(321); + p1.setPacketSize(128); + p1.setMaxFlowWndSize(128); + p1.setSocketID(1); + p1.setUdtVersion(4); + + + byte[]p1_data=p1.getEncoded(); + + UDTPacket p=PacketFactory.createPacket(p1_data); + ConnectionHandshake p2=(ConnectionHandshake)p; + assertEquals(p1,p2); + + } + + public void testAcknowledgement(){ + Acknowledgement p1 = new Acknowledgement(); + p1.setAckSequenceNumber(1234); + p1.setMessageNumber(9876); + p1.setTimeStamp(3456); + p1.setDestinationID(1); + p1.setBufferSize(128); + p1.setEstimatedLinkCapacity(16); + p1.setAckNumber(9870); + p1.setPacketReceiveRate(1000); + p1.setRoundTripTime(1000); + p1.setRoundTripTimeVar(500); + + byte[]p1_data=p1.getEncoded(); + UDTPacket p=PacketFactory.createPacket(p1_data); + Acknowledgement p2=(Acknowledgement)p; + assertEquals(p1,p2); + } + + public void testAcknowledgementOfAcknowledgement(){ + Acknowledgment2 p1 = new Acknowledgment2(); + p1.setAckSequenceNumber(1230); + p1.setMessageNumber(9871); + p1.setTimeStamp(3451); + p1.setDestinationID(1); + + byte[]p1_data=p1.getEncoded(); + UDTPacket p=PacketFactory.createPacket(p1_data); + Acknowledgment2 p2=(Acknowledgment2)p; + assertEquals(p1,p2); + + + } + + public void testNegativeAcknowledgement(){ + NegativeAcknowledgement p1 = new NegativeAcknowledgement(); + p1.setMessageNumber(9872); + p1.setTimeStamp(3452); + p1.setDestinationID(2); + p1.addLossInfo(5); + p1.addLossInfo(6); + p1.addLossInfo(7, 10); + byte[]p1_data=p1.getEncoded(); + + UDTPacket p=PacketFactory.createPacket(p1_data); + NegativeAcknowledgement p2=(NegativeAcknowledgement)p; + assertEquals(p1,p2); + + assertEquals((Integer)5, (Integer)p2.getDecodedLossInfo().get(0)); + assertEquals(6, p2.getDecodedLossInfo().size()); + } + + public void testNegativeAcknowledgement2(){ + NegativeAcknowledgement p1 = new NegativeAcknowledgement(); + p1.setMessageNumber(9872); + p1.setTimeStamp(3452); + p1.setDestinationID(2); + List<Long>loss=new ArrayList<Long>(); + loss.add(5l); + loss.add(6l); + loss.add(7l); + loss.add(8l); + loss.add(9l); + loss.add(11l); + + p1.addLossInfo(loss); + byte[]p1_data=p1.getEncoded(); + + UDTPacket p=PacketFactory.createPacket(p1_data); + NegativeAcknowledgement p2=(NegativeAcknowledgement)p; + assertEquals(p1,p2); + + assertEquals((Integer)5, (Integer)p2.getDecodedLossInfo().get(0)); + assertEquals(6, p2.getDecodedLossInfo().size()); + } + + public void testNegativeAcknowledgement3(){ + NegativeAcknowledgement p1 = new NegativeAcknowledgement(); + p1.setMessageNumber(9872); + p1.setTimeStamp(3452); + p1.setDestinationID(2); + p1.addLossInfo(5); + p1.addLossInfo(6); + p1.addLossInfo(147, 226); + byte[]p1_data=p1.getEncoded(); + + UDTPacket p=PacketFactory.createPacket(p1_data); + NegativeAcknowledgement p2=(NegativeAcknowledgement)p; + assertEquals(p1,p2); + + + } + + public void testShutdown(){ + Shutdown p1 = new Shutdown(); + p1.setMessageNumber(9874); + p1.setTimeStamp(3453); + p1.setDestinationID(3); + + + byte[]p1_data=p1.getEncoded(); + + UDTPacket p=PacketFactory.createPacket(p1_data); + Shutdown p2=(Shutdown)p; + assertEquals(p1,p2); + } + + + + public void testMessageDropRequest(){ + MessageDropRequest p1=new MessageDropRequest(); + p1.setMessageNumber(9876); + p1.setTimeStamp(3456); + p1.setDestinationID(4); + + p1.setMsgFirstSeqNo(2); + p1.setMsgLastSeqNo(3); + + + byte[]p1_data=p1.getEncoded(); + + UDTPacket p=PacketFactory.createPacket(p1_data); + assertTrue(p instanceof MessageDropRequest); + MessageDropRequest p2=(MessageDropRequest)p; + assertEquals(p1,p2); + } + +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2010-09-15 19:22:25
|
Revision: 49 http://udt-java.svn.sourceforge.net/udt-java/?rev=49&view=rev Author: bschuller Date: 2010-09-15 19:22:18 +0000 (Wed, 15 Sep 2010) Log Message: ----------- simpler way to implement a receive buffer Modified Paths: -------------- udt-java/trunk/src/main/java/udt/UDTInputStream.java udt-java/trunk/src/main/java/udt/UDTReceiver.java udt-java/trunk/src/main/java/udt/UDTSession.java udt-java/trunk/src/test/java/udt/TestUDTInputStream.java udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java Added Paths: ----------- udt-java/trunk/src/main/java/udt/util/ReceiveBuffer.java udt-java/trunk/src/test/java/udt/util/ udt-java/trunk/src/test/java/udt/util/TestReceiveBuffer.java Modified: udt-java/trunk/src/main/java/udt/UDTInputStream.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTInputStream.java 2010-09-13 18:55:07 UTC (rev 48) +++ udt-java/trunk/src/main/java/udt/UDTInputStream.java 2010-09-15 19:22:18 UTC (rev 49) @@ -34,12 +34,10 @@ import java.io.IOException; import java.io.InputStream; -import java.util.concurrent.PriorityBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import udt.util.SequenceNumber; -import udt.util.UDTStatistics; +import udt.util.ReceiveBuffer; /** * The UDTInputStream receives data blocks from the {@link UDTSocket} @@ -53,16 +51,8 @@ //the socket owning this inputstream private final UDTSocket socket; - //inbound application data, in-order, and ready for reading - //by the application - private final PriorityBlockingQueue<AppData>appData; + private final ReceiveBuffer receiveBuffer; - private final UDTStatistics statistics; - - //the highest sequence number read by the application, initialised - //to the initial sequence number minus one - private volatile long highestSequenceNumber=0; - //set to 'false' by the receiver when it gets a shutdown signal from the peer //see the noMoreData() method private final AtomicBoolean expectMoreData=new AtomicBoolean(true); @@ -74,28 +64,15 @@ /** * create a new {@link UDTInputStream} connected to the given socket * @param socket - the {@link UDTSocket} - * @param statistics - the {@link UDTStatistics} * @throws IOException */ - public UDTInputStream(UDTSocket socket, UDTStatistics statistics)throws IOException{ + public UDTInputStream(UDTSocket socket)throws IOException{ this.socket=socket; - this.statistics=statistics; - int capacity=socket!=null? 4*socket.getSession().getFlowWindowSize() : 64 ; - appData=new PriorityBlockingQueue<AppData>(capacity); - if(socket!=null){ - highestSequenceNumber=SequenceNumber.decrement(socket.getSession().getInitialSequenceNumber()); - } + int capacity=socket!=null? 2 * socket.getSession().getFlowWindowSize() : 128 ; + long initialSequenceNum=socket!=null?socket.getSession().getInitialSequenceNumber():1; + receiveBuffer=new ReceiveBuffer(capacity,initialSequenceNum); } - /** - * create a new {@link UDTInputStream} connected to the given socket - * @param socket - the {@link UDTSocket} - * @throws IOException - */ - public UDTInputStream(UDTSocket socket)throws IOException{ - this(socket, socket.getSession().getStatistics()); - } - private final byte[]single=new byte[1]; @Override @@ -143,7 +120,7 @@ if(read>0)return read; if(closed)return -1; - if(expectMoreData.get() || !appData.isEmpty())return 0; + if(expectMoreData.get() || !receiveBuffer.isEmpty())return 0; //no more data return -1; @@ -168,38 +145,19 @@ while(true){ try{ if(block){ - currentChunk=appData.poll(1, TimeUnit.MILLISECONDS); + currentChunk=receiveBuffer.poll(1, TimeUnit.MILLISECONDS); while (!closed && currentChunk==null){ - currentChunk=appData.poll(1000, TimeUnit.MILLISECONDS); + currentChunk=receiveBuffer.poll(1000, TimeUnit.MILLISECONDS); } } - else currentChunk=appData.poll(10, TimeUnit.MILLISECONDS); + else currentChunk=receiveBuffer.poll(10, TimeUnit.MILLISECONDS); }catch(InterruptedException ie){ IOException ex=new IOException(); ex.initCause(ie); throw ex; } - if(currentChunk!=null){ - //check if the data is in-order - long cmp=SequenceNumber.compare(currentChunk.sequenceNumber,highestSequenceNumber+1); - if(cmp==0){ - highestSequenceNumber=currentChunk.sequenceNumber; - return; - } - else if(cmp<0){ - //duplicate, drop it - currentChunk=null; - statistics.incNumberOfDuplicateDataPackets(); - } - else{ - //out of order data, put back into queue and exit - appData.offer(currentChunk); - currentChunk=null; - return; - } - } - else return; + return; } } @@ -209,8 +167,7 @@ * */ protected boolean haveNewData(long sequenceNumber,byte[]data)throws IOException{ - if(SequenceNumber.compare(sequenceNumber,highestSequenceNumber)<=0)return true; - return appData.offer(new AppData(sequenceNumber,data)); + return receiveBuffer.offer(new AppData(sequenceNumber,data)); } @Override @@ -232,6 +189,10 @@ this.blocking=block; } + public int getReceiveBufferSize(){ + return receiveBuffer.getSize(); + } + /** * notify the input stream that there is no more data * @throws IOException @@ -247,7 +208,7 @@ public static class AppData implements Comparable<AppData>{ final long sequenceNumber; final byte[] data; - AppData(long sequenceNumber, byte[]data){ + public AppData(long sequenceNumber, byte[]data){ this.sequenceNumber=sequenceNumber; this.data=data; } @@ -260,6 +221,10 @@ return sequenceNumber+"["+data.length+"]"; } + public long getSequenceNumber(){ + return sequenceNumber; + } + @Override public int hashCode() { final int prime = 31; Modified: udt-java/trunk/src/main/java/udt/UDTReceiver.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-09-13 18:55:07 UTC (rev 48) +++ udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-09-15 19:22:18 UTC (rev 49) @@ -388,12 +388,17 @@ //check whether to drop this packet // n++; - //if(dropRate>0 && n % dropRate == 0){ +// //if(dropRate>0 && n % dropRate == 0){ // if(n==666){ // logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); // return; // } - +// + boolean OK=session.getSocket().getInputStream().haveNewData(currentSequenceNumber,dp.getData()); + if(!OK){ + //need to drop packet... + return; + } long currentDataPacketArrivalTime = Util.getCurrentTime(); @@ -412,7 +417,6 @@ //store current time lastDataPacketArrivalTime=currentDataPacketArrivalTime; - session.getSocket().getInputStream().haveNewData(currentSequenceNumber,dp.getData()); //(6).number of detected lossed packet /*(6.a).if the number of the current data packet is greater than LSRN+1, Modified: udt-java/trunk/src/main/java/udt/UDTSession.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSession.java 2010-09-13 18:55:07 UTC (rev 48) +++ udt-java/trunk/src/main/java/udt/UDTSession.java 2010-09-15 19:22:18 UTC (rev 49) @@ -74,7 +74,7 @@ * flow window size, i.e. how many data packets are * in-flight at a single time */ - protected int flowWindowSize=8192;//4*128; + protected int flowWindowSize=1024; /** * remote UDT entity (address and socket ID) Added: udt-java/trunk/src/main/java/udt/util/ReceiveBuffer.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/ReceiveBuffer.java (rev 0) +++ udt-java/trunk/src/main/java/udt/util/ReceiveBuffer.java 2010-09-15 19:22:18 UTC (rev 49) @@ -0,0 +1,149 @@ +package udt.util; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import udt.UDTInputStream.AppData; + +/** + * + * The receive buffer stores data chunks to be read by the application + * + * @author schuller + */ +public class ReceiveBuffer { + + private final AppData[]buffer; + + //the head of the buffer: contains the next chunk to be read by the application, + //i.e. the one with the lowest sequence number + private volatile int readPosition=0; + + //the lowest sequence number stored in this buffer + private final long initialSequenceNumber; + + //the highest sequence number already read by the application + private long highestReadSequenceNumber; + + //number of chunks + private final AtomicInteger numValidChunks=new AtomicInteger(0); + + //lock and condition for poll() with timeout + private final Condition notEmpty; + private final ReentrantLock lock; + + //the size of the buffer + private final int size; + + public ReceiveBuffer(int size, long initialSequenceNumber){ + this.size=size; + this.buffer=new AppData[size]; + this.initialSequenceNumber=initialSequenceNumber; + lock=new ReentrantLock(false); + notEmpty=lock.newCondition(); + highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); + System.out.println("SIZE: "+size); + } + + public boolean offer(AppData data){ + if(numValidChunks.get()==size) { + return false; + } + lock.lock(); + try{ + long seq=data.getSequenceNumber(); + //if already have this chunk, discard it + if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + //else compute insert position + int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); + int insert=offset% size; + buffer[insert]=data; + numValidChunks.incrementAndGet(); + return true; + }finally{ + lock.unlock(); + } + } + + /** + * return a data chunk, guaranteed to be in-order, waiting up to the + * specified wait time if necessary for a chunk to become available. + * + * @param timeout how long to wait before giving up, in units of + * <tt>unit</tt> + * @param unit a <tt>TimeUnit</tt> determining how to interpret the + * <tt>timeout</tt> parameter + * @return data chunk, or <tt>null</tt> if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public AppData poll(int timeout, TimeUnit units)throws InterruptedException{ + lock.lockInterruptibly(); + long nanos = units.toNanos(timeout); + + try { + for (;;) { + if (numValidChunks.get() != 0) { + return poll(); + } + if (nanos <= 0) + return null; + try { + nanos = notEmpty.awaitNanos(nanos); + } catch (InterruptedException ie) { + notEmpty.signal(); // propagate to non-interrupted thread + throw ie; + } + + } + } finally { + lock.unlock(); + } + } + + + /** + * return a data chunk, guaranteed to be in-order. + */ + public AppData poll(){ + if(numValidChunks.get()==0){ + return null; + } + AppData r=buffer[readPosition]; + if(r!=null){ + long thisSeq=r.getSequenceNumber(); + if(1==SequenceNumber.seqOffset(highestReadSequenceNumber,thisSeq)){ + increment(); + highestReadSequenceNumber=thisSeq; + } + else return null; + } + // else{ + // System.out.println("empty HEAD at pos="+readPosition); + // try{ + // Thread.sleep(1000); + // Thread.yield(); + // }catch(InterruptedException e){}; + // } + + return r; + } + + public int getSize(){ + return size; + } + + void increment(){ + buffer[readPosition]=null; + readPosition++; + if(readPosition==size)readPosition=0; + numValidChunks.decrementAndGet(); + } + + public boolean isEmpty(){ + return numValidChunks.get()==0; + } + +} Property changes on: udt-java/trunk/src/main/java/udt/util/ReceiveBuffer.java ___________________________________________________________________ Added: svn:mime-type + text/plain Modified: udt-java/trunk/src/test/java/udt/TestUDTInputStream.java =================================================================== --- udt-java/trunk/src/test/java/udt/TestUDTInputStream.java 2010-09-13 18:55:07 UTC (rev 48) +++ udt-java/trunk/src/test/java/udt/TestUDTInputStream.java 2010-09-15 19:22:18 UTC (rev 49) @@ -1,15 +1,17 @@ package udt; import java.security.MessageDigest; +import java.util.concurrent.Callable; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; -import udt.util.UDTStatistics; import udt.util.Util; public class TestUDTInputStream extends UDTTestBase{ public void test1()throws Exception{ - UDTStatistics stat=new UDTStatistics("test"); - UDTInputStream is=new UDTInputStream(null, stat); + UDTInputStream is=new UDTInputStream(null); byte[] data1="this is ".getBytes(); byte[] data2="a test".getBytes(); byte[] data3=" string".getBytes(); @@ -24,8 +26,7 @@ } public void test2()throws Exception{ - UDTStatistics stat=new UDTStatistics("test"); - UDTInputStream is=new UDTInputStream(null, stat); + UDTInputStream is=new UDTInputStream(null); byte[] data1=getRandomData(65537); byte[] data2=getRandomData(1234); byte[] data3=getRandomData(3*1024*1024); @@ -40,8 +41,7 @@ } public void testInOrder()throws Exception{ - UDTStatistics stat=new UDTStatistics("test"); - UDTInputStream is=new UDTInputStream(null, stat); + UDTInputStream is=new UDTInputStream(null); is.setBlocking(false); byte[]data=getRandomData(10*1024*1024); @@ -58,8 +58,7 @@ } public void testRandomOrder()throws Exception{ - UDTStatistics stat=new UDTStatistics("test"); - UDTInputStream is=new UDTInputStream(null, stat); + UDTInputStream is=new UDTInputStream(null); is.setBlocking(false); byte[]data=getRandomData(100*1024); @@ -76,6 +75,50 @@ assertEquals(digest,readMD5); } + + + public void testLargeDataSetTwoThreads()throws Exception{ + final UDTInputStream is=new UDTInputStream(null); + is.setBlocking(false); + int n=100; + assertTrue("ERROR IN UNIT TEST : too many packets!",n<=is.getReceiveBufferSize()); + final byte[]data=getRandomData(n*1024); + final byte[][]blocks=makeChunks(n,data); + String digest=computeMD5(blocks); + + Runnable write=new Runnable(){ + public void run(){ + try{ + for(int i=0;i<blocks.length;i++){ + while(!is.haveNewData(i+1, blocks[i])){ + Thread.yield(); + Thread.sleep(100); + } + } + is.noMoreData(); + }catch(Exception e){ + e.printStackTrace(); + fail(); + } + } + }; + + Callable<String> reader=new Callable<String>(){ + public String call() throws Exception { + String md5=readAll(is,1024*999); + return md5; + } + }; + + ScheduledExecutorService es=Executors.newScheduledThreadPool(2); + es.execute(write); + Future<String> result=es.submit(reader); + String readMD5=result.get(); + + assertEquals(digest,readMD5); + es.shutdownNow(); + } + //read and discard data from the given input stream //returns the md5 digest of the data protected String readAll(UDTInputStream is, int bufsize,boolean sendNoMoreData)throws Exception{ Modified: udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-09-13 18:55:07 UTC (rev 48) +++ udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-09-15 19:22:18 UTC (rev 49) @@ -21,7 +21,7 @@ boolean running=false; //how many - int num_packets=50; + int num_packets=500; //how large is a single packet int size=1*1024*1024; Added: udt-java/trunk/src/test/java/udt/util/TestReceiveBuffer.java =================================================================== --- udt-java/trunk/src/test/java/udt/util/TestReceiveBuffer.java (rev 0) +++ udt-java/trunk/src/test/java/udt/util/TestReceiveBuffer.java 2010-09-15 19:22:18 UTC (rev 49) @@ -0,0 +1,142 @@ +package udt.util; + +import java.util.concurrent.Callable; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import junit.framework.TestCase; +import udt.UDTInputStream.AppData; + +public class TestReceiveBuffer extends TestCase{ + + public void testInOrder(){ + ReceiveBuffer b=new ReceiveBuffer(16,1); + byte[]test1="test1".getBytes(); + byte[]test2="test2".getBytes(); + byte[]test3="test3".getBytes(); + + b.offer(new AppData(1l,test1)); + b.offer(new AppData(2l,test2)); + b.offer(new AppData(3l,test3)); + + AppData a=b.poll(); + assertEquals(1l,a.getSequenceNumber()); + + a=b.poll(); + assertEquals(2l,a.getSequenceNumber()); + + a=b.poll(); + assertEquals(3l,a.getSequenceNumber()); + + assertNull(b.poll()); + } + + public void testOutOfOrder(){ + ReceiveBuffer b=new ReceiveBuffer(16,1); + byte[]test1="test1".getBytes(); + byte[]test2="test2".getBytes(); + byte[]test3="test3".getBytes(); + + b.offer(new AppData(3l,test3)); + b.offer(new AppData(2l,test2)); + b.offer(new AppData(1l,test1)); + + AppData a=b.poll(); + assertEquals(1l,a.getSequenceNumber()); + + a=b.poll(); + assertEquals(2l,a.getSequenceNumber()); + + a=b.poll(); + assertEquals(3l,a.getSequenceNumber()); + + assertNull(b.poll()); + } + + public void testInterleaved(){ + ReceiveBuffer b=new ReceiveBuffer(16,1); + byte[]test1="test1".getBytes(); + byte[]test2="test2".getBytes(); + byte[]test3="test3".getBytes(); + + b.offer(new AppData(3l,test3)); + + b.offer(new AppData(1l,test1)); + + AppData a=b.poll(); + assertEquals(1l,a.getSequenceNumber()); + + assertNull(b.poll()); + + b.offer(new AppData(2l,test2)); + + a=b.poll(); + assertEquals(2l,a.getSequenceNumber()); + + a=b.poll(); + assertEquals(3l,a.getSequenceNumber()); + } + + public void testOverflow(){ + ReceiveBuffer b=new ReceiveBuffer(4,1); + + for(int i=0; i<3; i++){ + b.offer(new AppData(i+1,"test".getBytes())); + } + for(int i=0; i<3; i++){ + assertEquals(i+1, b.poll().getSequenceNumber()); + } + + for(int i=0; i<3; i++){ + b.offer(new AppData(i+4,"test".getBytes())); + } + for(int i=0; i<3; i++){ + assertEquals(i+4, b.poll().getSequenceNumber()); + } + } + + + public void testTimedPoll()throws Exception{ + final ReceiveBuffer b=new ReceiveBuffer(4,1); + + Runnable write=new Runnable(){ + + public void run(){ + try{ + for(int i=0; i<5; i++){ + Thread.sleep(500); + b.offer(new AppData(i+1,"test".getBytes())); + } + }catch(Exception e){ + e.printStackTrace(); + fail(); + } + } + }; + + Callable<String> reader=new Callable<String>(){ + public String call() throws Exception { + for(int i=0; i<5; i++){ + AppData r=null; + do{ + try{ + r=b.poll(200, TimeUnit.MILLISECONDS); + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + }while(r==null); + } + return "OK."; + } + }; + + ScheduledExecutorService es=Executors.newScheduledThreadPool(2); + es.execute(write); + Future<String>res=es.submit(reader); + res.get(); + es.shutdownNow(); + } + +} Property changes on: udt-java/trunk/src/test/java/udt/util/TestReceiveBuffer.java ___________________________________________________________________ Added: svn:mime-type + text/plain This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2010-09-17 11:04:46
|
Revision: 50 http://udt-java.svn.sourceforge.net/udt-java/?rev=50&view=rev Author: bschuller Date: 2010-09-17 11:04:39 +0000 (Fri, 17 Sep 2010) Log Message: ----------- Modified Paths: -------------- udt-java/trunk/src/main/java/udt/UDTReceiver.java udt-java/trunk/src/main/java/udt/util/ReceiveBuffer.java udt-java/trunk/src/main/java/udt/util/ReceiveFile.java udt-java/trunk/src/main/java/udt/util/Util.java udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java udt-java/trunk/src/test/java/udt/util/TestReceiveBuffer.java Modified: udt-java/trunk/src/main/java/udt/UDTReceiver.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-09-15 19:22:18 UTC (rev 49) +++ udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-09-17 11:04:39 UTC (rev 50) @@ -386,14 +386,14 @@ protected void onDataPacketReceived(DataPacket dp)throws IOException{ long currentSequenceNumber = dp.getPacketSequenceNumber(); - //check whether to drop this packet + //for TESTING : check whether to drop this packet // n++; // //if(dropRate>0 && n % dropRate == 0){ -// if(n==666){ -// logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); -// return; -// } -// +// if(n % 1111 == 0){ +// logger.info("**** TESTING:::: DROPPING PACKET "+currentSequenceNumber+" FOR TESTING"); +// return; +// } +// //} boolean OK=session.getSocket().getInputStream().haveNewData(currentSequenceNumber,dp.getData()); if(!OK){ //need to drop packet... Modified: udt-java/trunk/src/main/java/udt/util/ReceiveBuffer.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/ReceiveBuffer.java 2010-09-15 19:22:18 UTC (rev 49) +++ udt-java/trunk/src/main/java/udt/util/ReceiveBuffer.java 2010-09-17 11:04:39 UTC (rev 50) @@ -61,6 +61,7 @@ int insert=offset% size; buffer[insert]=data; numValidChunks.incrementAndGet(); + notEmpty.signal(); return true; }finally{ lock.unlock(); Modified: udt-java/trunk/src/main/java/udt/util/ReceiveFile.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/ReceiveFile.java 2010-09-15 19:22:18 UTC (rev 49) +++ udt-java/trunk/src/main/java/udt/util/ReceiveFile.java 2010-09-17 11:04:39 UTC (rev 50) @@ -32,8 +32,10 @@ package udt.util; +import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; +import java.io.OutputStream; import java.net.InetAddress; import java.text.NumberFormat; @@ -101,22 +103,16 @@ total+=r; } long size=decode(sizeInfo, 0); - if(verbose){ - StringBuilder sb=new StringBuilder(); - for(int i=0;i<sizeInfo.length;i++){ - sb.append(Integer.toString(sizeInfo[i])); - sb.append(" "); - } - System.out.println("[ReceiveFile] Size info: "+sb.toString()); - } + File file=new File(new String(localFile)); System.out.println("[ReceiveFile] Write to local file <"+file.getAbsolutePath()+">"); FileOutputStream fos=new FileOutputStream(file); + OutputStream os=new BufferedOutputStream(fos,1024*1024); try{ System.out.println("[ReceiveFile] Reading <"+size+"> bytes."); long start = System.currentTimeMillis(); //and read the file data - Util.copy(in, fos, size, false); + Util.copy(in, os, size, false); long end = System.currentTimeMillis(); double rate=1000.0*size/1024/1024/(end-start); System.out.println("[ReceiveFile] Rate: "+format.format(rate)+" MBytes/sec. " Modified: udt-java/trunk/src/main/java/udt/util/Util.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/Util.java 2010-09-15 19:22:18 UTC (rev 49) +++ udt-java/trunk/src/main/java/udt/util/Util.java 2010-09-17 11:04:39 UTC (rev 50) @@ -134,6 +134,7 @@ c=source.read(buf); if(c<0)break; read+=c; + //System.out.println("writing <"+c+"> bytes"); target.write(buf, 0, c); if(flush)target.flush(); if(read>=size && size>-1)break; Modified: udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-09-15 19:22:18 UTC (rev 49) +++ udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-09-17 11:04:39 UTC (rev 50) @@ -21,7 +21,7 @@ boolean running=false; //how many - int num_packets=500; + int num_packets=200; //how large is a single packet int size=1*1024*1024; Modified: udt-java/trunk/src/test/java/udt/util/TestReceiveBuffer.java =================================================================== --- udt-java/trunk/src/test/java/udt/util/TestReceiveBuffer.java 2010-09-15 19:22:18 UTC (rev 49) +++ udt-java/trunk/src/test/java/udt/util/TestReceiveBuffer.java 2010-09-17 11:04:39 UTC (rev 50) @@ -16,79 +16,79 @@ byte[]test1="test1".getBytes(); byte[]test2="test2".getBytes(); byte[]test3="test3".getBytes(); - + b.offer(new AppData(1l,test1)); b.offer(new AppData(2l,test2)); b.offer(new AppData(3l,test3)); - + AppData a=b.poll(); assertEquals(1l,a.getSequenceNumber()); - + a=b.poll(); assertEquals(2l,a.getSequenceNumber()); - + a=b.poll(); assertEquals(3l,a.getSequenceNumber()); - + assertNull(b.poll()); } - + public void testOutOfOrder(){ ReceiveBuffer b=new ReceiveBuffer(16,1); byte[]test1="test1".getBytes(); byte[]test2="test2".getBytes(); byte[]test3="test3".getBytes(); - + b.offer(new AppData(3l,test3)); b.offer(new AppData(2l,test2)); b.offer(new AppData(1l,test1)); - + AppData a=b.poll(); assertEquals(1l,a.getSequenceNumber()); - + a=b.poll(); assertEquals(2l,a.getSequenceNumber()); - + a=b.poll(); assertEquals(3l,a.getSequenceNumber()); - + assertNull(b.poll()); } - + public void testInterleaved(){ ReceiveBuffer b=new ReceiveBuffer(16,1); byte[]test1="test1".getBytes(); byte[]test2="test2".getBytes(); byte[]test3="test3".getBytes(); - + b.offer(new AppData(3l,test3)); - + b.offer(new AppData(1l,test1)); - + AppData a=b.poll(); assertEquals(1l,a.getSequenceNumber()); - + assertNull(b.poll()); - + b.offer(new AppData(2l,test2)); - + a=b.poll(); assertEquals(2l,a.getSequenceNumber()); - + a=b.poll(); assertEquals(3l,a.getSequenceNumber()); } - + public void testOverflow(){ ReceiveBuffer b=new ReceiveBuffer(4,1); - + for(int i=0; i<3; i++){ b.offer(new AppData(i+1,"test".getBytes())); } for(int i=0; i<3; i++){ assertEquals(i+1, b.poll().getSequenceNumber()); } - + for(int i=0; i<3; i++){ b.offer(new AppData(i+4,"test".getBytes())); } @@ -96,13 +96,13 @@ assertEquals(i+4, b.poll().getSequenceNumber()); } } - - + + public void testTimedPoll()throws Exception{ final ReceiveBuffer b=new ReceiveBuffer(4,1); - + Runnable write=new Runnable(){ - + public void run(){ try{ for(int i=0; i<5; i++){ @@ -115,7 +115,7 @@ } } }; - + Callable<String> reader=new Callable<String>(){ public String call() throws Exception { for(int i=0; i<5; i++){ @@ -131,12 +131,60 @@ return "OK."; } }; + + ScheduledExecutorService es=Executors.newScheduledThreadPool(2); + es.execute(write); + Future<String>res=es.submit(reader); + res.get(); + es.shutdownNow(); + } + + + volatile boolean poll=false; + + public void testTimedPoll2()throws Exception{ + final ReceiveBuffer b=new ReceiveBuffer(4,1); + Runnable write=new Runnable(){ + + public void run(){ + try{ + Thread.sleep(2979); + System.out.println("PUT"); + while(!poll)Thread.sleep(10); + b.offer(new AppData(1,"test".getBytes())); + System.out.println("... PUT OK"); + } + catch(Exception e){ + e.printStackTrace(); + fail(); + } + } + }; + + Callable<String> reader=new Callable<String>(){ + public String call() throws Exception { + AppData r=null; + do{ + try{ + poll=true; + System.out.println("POLL"); + r=b.poll(1000, TimeUnit.MILLISECONDS); + poll=false; + if(r!=null)System.out.println("... POLL OK"); + else System.out.println("... nothing."); + }catch(InterruptedException ie){ + ie.printStackTrace(); + } + }while(r==null); + return "OK."; + } + }; + ScheduledExecutorService es=Executors.newScheduledThreadPool(2); es.execute(write); Future<String>res=es.submit(reader); res.get(); es.shutdownNow(); } - } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2010-11-11 23:22:55
|
Revision: 52 http://udt-java.svn.sourceforge.net/udt-java/?rev=52&view=rev Author: bschuller Date: 2010-11-11 21:56:26 +0000 (Thu, 11 Nov 2010) Log Message: ----------- fix sender loss list (entries were not ordered) Modified Paths: -------------- udt-java/trunk/src/main/java/udt/sender/SenderLossList.java udt-java/trunk/src/test/java/udt/TestList.java Modified: udt-java/trunk/src/main/java/udt/sender/SenderLossList.java =================================================================== --- udt-java/trunk/src/main/java/udt/sender/SenderLossList.java 2010-09-23 09:09:56 UTC (rev 51) +++ udt-java/trunk/src/main/java/udt/sender/SenderLossList.java 2010-11-11 21:56:26 UTC (rev 52) @@ -51,7 +51,7 @@ synchronized (backingList) { if(!backingList.contains(obj)){ for(int i=0;i<backingList.size();i++){ - if(obj<backingList.getFirst()){ + if(obj<backingList.get(i)){ backingList.add(i,obj); return; } Modified: udt-java/trunk/src/test/java/udt/TestList.java =================================================================== --- udt-java/trunk/src/test/java/udt/TestList.java 2010-09-23 09:09:56 UTC (rev 51) +++ udt-java/trunk/src/test/java/udt/TestList.java 2010-11-11 21:56:26 UTC (rev 52) @@ -88,6 +88,10 @@ assertEquals(3,l.size()); Long oldest=l.getFirstEntry(); assertEquals(C,oldest); + oldest=l.getFirstEntry(); + assertEquals(A,oldest); + oldest=l.getFirstEntry(); + assertEquals(B,oldest); } public void testReceiverInputQueue(){ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2011-01-06 16:13:38
|
Revision: 53 http://udt-java.svn.sourceforge.net/udt-java/?rev=53&view=rev Author: bschuller Date: 2011-01-06 16:13:32 +0000 (Thu, 06 Jan 2011) Log Message: ----------- Modified Paths: -------------- udt-java/trunk/src/main/java/udt/UDPEndPoint.java udt-java/trunk/src/main/java/udt/UDTClient.java udt-java/trunk/src/main/java/udt/UDTReceiver.java udt-java/trunk/src/main/java/udt/UDTSender.java udt-java/trunk/src/main/java/udt/sender/SenderLossList.java udt-java/trunk/src/main/java/udt/util/MeanValue.java udt-java/trunk/src/main/java/udt/util/ReceiveBuffer.java udt-java/trunk/src/main/java/udt/util/ReceiveFile.java udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java udt-java/trunk/src/test/java/udt/performance/UDPTest.java Modified: udt-java/trunk/src/main/java/udt/UDPEndPoint.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDPEndPoint.java 2010-11-11 21:56:26 UTC (rev 52) +++ udt-java/trunk/src/main/java/udt/UDPEndPoint.java 2011-01-06 16:13:32 UTC (rev 53) @@ -117,12 +117,17 @@ if(localPort>0)this.port = localPort; else port=dgSocket.getLocalPort(); + configureSocket(); + } + + protected void configureSocket()throws SocketException{ //set a time out to avoid blocking in doReceive() dgSocket.setSoTimeout(100000); //buffer size dgSocket.setReceiveBufferSize(128*1024); + dgSocket.setReuseAddress(false); } - + /** * bind to the default network interface on the machine * @@ -237,8 +242,6 @@ private long lastDestID=-1; private UDTSession lastSession; - //MeanValue v=new MeanValue("receiver processing ",true, 256); - private int n=0; private final Object lock=new Object(); @@ -247,13 +250,10 @@ while(!stopped){ try{ try{ - //v.end(); //will block until a packet is received or timeout has expired dgSocket.receive(dp); - //v.begin(); - Destination peer=new Destination(dp.getAddress(), dp.getPort()); int l=dp.getLength(); UDTPacket packet=PacketFactory.createPacket(dp.getData(),l); Modified: udt-java/trunk/src/main/java/udt/UDTClient.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTClient.java 2010-11-11 21:56:26 UTC (rev 52) +++ udt-java/trunk/src/main/java/udt/UDTClient.java 2011-01-06 16:13:32 UTC (rev 53) @@ -93,14 +93,19 @@ /** * sends the given data asynchronously * - * @param data + * @param data - the data to send * @throws IOException - * @throws InterruptedException */ - public void send(byte[]data)throws IOException, InterruptedException{ + public void send(byte[]data)throws IOException{ clientSession.getSocket().doWrite(data); } + /** + * sends the given data and waits for acknowledgement + * @param data - the data to send + * @throws IOException + * @throws InterruptedException if interrupted while waiting for ack + */ public void sendBlocking(byte[]data)throws IOException, InterruptedException{ clientSession.getSocket().doWriteBlocking(data); } Modified: udt-java/trunk/src/main/java/udt/UDTReceiver.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTReceiver.java 2010-11-11 21:56:26 UTC (rev 52) +++ udt-java/trunk/src/main/java/udt/UDTReceiver.java 2011-01-06 16:13:32 UTC (rev 53) @@ -183,13 +183,13 @@ private MeanValue dataProcessTime; private void initMetrics(){ if(!storeStatistics)return; - dgReceiveInterval=new MeanValue("UDT receive interval"); + dgReceiveInterval=new MeanValue("RECEIVER: UDT receive interval"); statistics.addMetric(dgReceiveInterval); - dataPacketInterval=new MeanValue("Data packet interval"); + dataPacketInterval=new MeanValue("RECEIVER: Data packet interval"); statistics.addMetric(dataPacketInterval); - processTime=new MeanValue("UDT packet process time"); + processTime=new MeanValue("RECEIVER: UDT packet process time"); statistics.addMetric(processTime); - dataProcessTime=new MeanValue("Data packet process time"); + dataProcessTime=new MeanValue("RECEIVER: Data packet process time"); statistics.addMetric(dataProcessTime); } Modified: udt-java/trunk/src/main/java/udt/UDTSender.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSender.java 2010-11-11 21:56:26 UTC (rev 52) +++ udt-java/trunk/src/main/java/udt/UDTSender.java 2011-01-06 16:13:32 UTC (rev 53) @@ -125,7 +125,7 @@ statistics=session.getStatistics(); senderLossList=new SenderLossList(); sendBuffer=new ConcurrentHashMap<Long, DataPacket>(session.getFlowWindowSize(),0.75f,2); - sendQueue = new ArrayBlockingQueue<DataPacket>(1000); + sendQueue = new ArrayBlockingQueue<DataPacket>(session.getFlowWindowSize(), /*fairness*/ true); lastAckSequenceNumber=session.getInitialSequenceNumber(); currentSequenceNumber=session.getInitialSequenceNumber()-1; waitForAckLatch.set(new CountDownLatch(1)); @@ -140,11 +140,11 @@ private MeanThroughput throughput; private void initMetrics(){ if(!storeStatistics)return; - dgSendTime=new MeanValue("Datagram send time"); + dgSendTime=new MeanValue("SENDER: Datagram send time"); statistics.addMetric(dgSendTime); - dgSendInterval=new MeanValue("Datagram send interval"); + dgSendInterval=new MeanValue("SENDER: Datagram send interval"); statistics.addMetric(dgSendInterval); - throughput=new MeanThroughput("Throughput", session.getDatagramSize()); + throughput=new MeanThroughput("SENDER: Throughput", session.getDatagramSize()); statistics.addMetric(throughput); } @@ -338,7 +338,7 @@ if(unAcknowledged<session.getCongestionControl().getCongestionWindowSize() && unAcknowledged<session.getFlowWindowSize()){ //check for application data - DataPacket dp=sendQueue.poll(Util.SYN,TimeUnit.MICROSECONDS); + DataPacket dp=sendQueue.poll(); if(dp!=null){ send(dp); largestSentSequenceNumber=dp.getPacketSequenceNumber(); Modified: udt-java/trunk/src/main/java/udt/sender/SenderLossList.java =================================================================== --- udt-java/trunk/src/main/java/udt/sender/SenderLossList.java 2010-11-11 21:56:26 UTC (rev 52) +++ udt-java/trunk/src/main/java/udt/sender/SenderLossList.java 2011-01-06 16:13:32 UTC (rev 53) @@ -33,6 +33,8 @@ package udt.sender; import java.util.LinkedList; +import udt.util.MeanValue; + /** * stores the sequence number of the lost packets in increasing order */ @@ -49,15 +51,15 @@ public void insert(Long obj){ synchronized (backingList) { - if(!backingList.contains(obj)){ - for(int i=0;i<backingList.size();i++){ - if(obj<backingList.get(i)){ - backingList.add(i,obj); - return; - } + for(int i=0;i<backingList.size();i++){ + Long entry=backingList.get(i); + if(obj<entry){ + backingList.add(i,obj); + return; } - backingList.add(obj); + else if(obj==entry)return; } + backingList.add(obj); } } @@ -69,7 +71,7 @@ return backingList.poll(); } } - + public boolean isEmpty(){ return backingList.isEmpty(); } Modified: udt-java/trunk/src/main/java/udt/util/MeanValue.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/MeanValue.java 2010-11-11 21:56:26 UTC (rev 52) +++ udt-java/trunk/src/main/java/udt/util/MeanValue.java 2011-01-06 16:13:32 UTC (rev 53) @@ -9,6 +9,8 @@ public class MeanValue { private double mean=0; + private double max=0; + private double min=0; private int n=0; @@ -43,9 +45,15 @@ public void addValue(double value){ mean=(mean*n+value)/(n+1); n++; + max=Math.max(max, value); + min=Math.min(max, value); + if(verbose && n % nValue == 0){ - if(msg!=null)System.out.println(msg+" "+getFormattedMean()); - else System.out.println(name+getFormattedMean()); + if(msg!=null)System.out.println(msg+" "+get()); + else System.out.println(name+" "+get()); + + max=0; + min=0; } } @@ -57,6 +65,10 @@ return format.format(getMean()); } + public String get(){ + return format.format(getMean())+" max="+format.format(max)+" min="+format.format(min); + } + public void clear(){ mean=0; n=0; Modified: udt-java/trunk/src/main/java/udt/util/ReceiveBuffer.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/ReceiveBuffer.java 2010-11-11 21:56:26 UTC (rev 52) +++ udt-java/trunk/src/main/java/udt/util/ReceiveBuffer.java 2011-01-06 16:13:32 UTC (rev 53) @@ -44,7 +44,6 @@ lock=new ReentrantLock(false); notEmpty=lock.newCondition(); highestReadSequenceNumber=SequenceNumber.decrement(initialSequenceNumber); - System.out.println("SIZE: "+size); } public boolean offer(AppData data){ @@ -121,14 +120,6 @@ } else return null; } - // else{ - // System.out.println("empty HEAD at pos="+readPosition); - // try{ - // Thread.sleep(1000); - // Thread.yield(); - // }catch(InterruptedException e){}; - // } - return r; } Modified: udt-java/trunk/src/main/java/udt/util/ReceiveFile.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/ReceiveFile.java 2010-11-11 21:56:26 UTC (rev 52) +++ udt-java/trunk/src/main/java/udt/util/ReceiveFile.java 2011-01-06 16:13:32 UTC (rev 53) @@ -104,6 +104,12 @@ } long size=decode(sizeInfo, 0); + Boolean devNull=Boolean.getBoolean("udt.dev.null"); + if(devNull){ + while(true)Thread.sleep(10000); + } + + File file=new File(new String(localFile)); System.out.println("[ReceiveFile] Write to local file <"+file.getAbsolutePath()+">"); FileOutputStream fos=new FileOutputStream(file); Modified: udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2010-11-11 21:56:26 UTC (rev 52) +++ udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2011-01-06 16:13:32 UTC (rev 53) @@ -21,7 +21,7 @@ boolean running=false; //how many - int num_packets=200; + int num_packets=300; //how large is a single packet int size=1*1024*1024; @@ -32,6 +32,8 @@ public void test1()throws Exception{ Logger.getLogger("udt").setLevel(Level.INFO); +// System.setProperty("udt.receiver.storeStatistics","true"); +// System.setProperty("udt.sender.storeStatistics","true"); UDTReceiver.dropRate=0; TIMEOUT=Integer.MAX_VALUE; doTest(); @@ -109,6 +111,10 @@ Runnable serverProcess=new Runnable(){ public void run(){ try{ + Boolean devNull=Boolean.getBoolean("udt.dev.null"); + if(devNull){ + while(true)Thread.sleep(10000); + } MessageDigest md5=MessageDigest.getInstance("MD5"); long start=System.currentTimeMillis(); UDTSocket s=serverSocket.accept(); Modified: udt-java/trunk/src/test/java/udt/performance/UDPTest.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/UDPTest.java 2010-11-11 21:56:26 UTC (rev 52) +++ udt-java/trunk/src/test/java/udt/performance/UDPTest.java 2011-01-06 16:13:32 UTC (rev 53) @@ -23,8 +23,10 @@ public void test1()throws Exception{ runServer(); runThirdThread(); + //client socket DatagramSocket s=new DatagramSocket(12345); + //generate a test array with random content N=num_packets*packetSize; byte[]data=new byte[packetSize]; @@ -34,32 +36,29 @@ dp.setAddress(InetAddress.getByName("localhost")); dp.setPort(65321); System.out.println("Sending "+num_packets+" data blocks of <"+packetSize+"> bytes"); - MeanValue v=new MeanValue("Datagram send time",false); - MeanValue v2=new MeanValue("Datagram send interval",false); - MeanValue v3=new MeanValue("Encoding time",false); + MeanValue dgSendTime=new MeanValue("Datagram send time",false); + MeanValue dgSendInterval=new MeanValue("Datagram send interval",false); for(int i=0;i<num_packets;i++){ DataPacket p=new DataPacket(); p.setData(data); - v3.begin(); dp.setData(p.getEncoded()); - v3.end(); - v2.end(); - v.begin(); + dgSendInterval.end(); + dgSendTime.begin(); s.send(dp); - v.end(); - v2.begin(); + dgSendTime.end(); + dgSendInterval.begin(); } System.out.println("Finished sending."); while(serverRunning)Thread.sleep(10); System.out.println("Server stopped."); long end=System.currentTimeMillis(); System.out.println("Done. Sending "+N/1024/1024+" Mbytes took "+(end-start)+" ms"); - System.out.println("Rate "+N/1000/(end-start)+" Mbytes/sec"); + float rate=N/1000/(end-start); + System.out.println("Rate "+rate+" Mbytes/sec "+(rate*8)+ " Mbit/sec"); System.out.println("Rate "+num_packets+" packets/sec"); - System.out.println("Mean send time "+v.getFormattedMean()+" microsec"); - System.out.println("Mean send interval "+v2.getFormattedMean()+" microsec"); - System.out.println("Datapacket encoding time "+v3.getFormattedMean()+" microsec"); + System.out.println("Mean send time "+dgSendTime.get()); + System.out.println("Mean send interval "+dgSendInterval.get()); System.out.println("Server received: "+total); } @@ -79,6 +78,7 @@ while(true){ serverSocket.receive(dp); handoff.offer(dp); + total+=dp.getLength(); } } catch(Exception e){ @@ -117,5 +117,5 @@ t.start(); } - + } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2011-02-17 21:24:39
|
Revision: 54 http://udt-java.svn.sourceforge.net/udt-java/?rev=54&view=rev Author: bschuller Date: 2011-02-17 21:24:32 +0000 (Thu, 17 Feb 2011) Log Message: ----------- bit of refactoring of sender to avoid memory allocations for data and data packets Modified Paths: -------------- udt-java/trunk/src/main/java/udt/UDPEndPoint.java udt-java/trunk/src/main/java/udt/UDTReceiver.java udt-java/trunk/src/main/java/udt/UDTSender.java udt-java/trunk/src/main/java/udt/UDTSession.java udt-java/trunk/src/main/java/udt/UDTSocket.java udt-java/trunk/src/main/java/udt/packets/DataPacket.java udt-java/trunk/src/main/java/udt/receiver/PacketHistoryWindow.java udt-java/trunk/src/main/java/udt/sender/SenderLossList.java udt-java/trunk/src/main/java/udt/util/ReceiveFile.java udt-java/trunk/src/main/java/udt/util/UDTStatistics.java udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java Added Paths: ----------- udt-java/trunk/src/main/java/udt/sender/FlowWindow.java udt-java/trunk/src/test/java/udt/sender/ udt-java/trunk/src/test/java/udt/sender/TestFlowWindow.java Modified: udt-java/trunk/src/main/java/udt/UDPEndPoint.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDPEndPoint.java 2011-01-06 16:13:32 UTC (rev 53) +++ udt-java/trunk/src/main/java/udt/UDPEndPoint.java 2011-02-17 21:24:32 UTC (rev 54) @@ -168,6 +168,7 @@ } }; Thread t=UDTThreadFactory.get().newThread(receive); + t.setName("UDPEndpoint-"+t.getName()); t.setDaemon(true); t.start(); logger.info("UDTEndpoint started."); Modified: udt-java/trunk/src/main/java/udt/UDTReceiver.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTReceiver.java 2011-01-06 16:13:32 UTC (rev 53) +++ udt-java/trunk/src/main/java/udt/UDTReceiver.java 2011-02-17 21:24:32 UTC (rev 54) @@ -214,6 +214,8 @@ } }; receiverThread=UDTThreadFactory.get().newThread(r); + String s=(session instanceof ServerSession)? "ServerSession": "ClientSession"; + receiverThread.setName("UDTReceiver-"+s+"-"+receiverThread.getName()); receiverThread.start(); } Modified: udt-java/trunk/src/main/java/udt/UDTSender.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSender.java 2011-01-06 16:13:32 UTC (rev 53) +++ udt-java/trunk/src/main/java/udt/UDTSender.java 2011-02-17 21:24:32 UTC (rev 54) @@ -33,9 +33,8 @@ package udt; import java.io.IOException; +import java.nio.ByteBuffer; import java.util.Map; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -49,6 +48,7 @@ import udt.packets.DataPacket; import udt.packets.KeepAlive; import udt.packets.NegativeAcknowledgement; +import udt.sender.FlowWindow; import udt.sender.SenderLossList; import udt.util.MeanThroughput; import udt.util.MeanValue; @@ -76,13 +76,12 @@ //senderLossList stores the sequence numbers of lost packets //fed back by the receiver through NAK pakets private final SenderLossList senderLossList; - + //sendBuffer stores the sent data packets and their sequence numbers - private final Map<Long,DataPacket>sendBuffer; - - //sendQueue contains the packets to send - private final BlockingQueue<DataPacket>sendQueue; - + private final Map<Long,byte[]>sendBuffer; + + private final FlowWindow flowWindow; + //thread reading packets from send queue and sending them private Thread senderThread; @@ -117,15 +116,18 @@ private final AtomicReference<CountDownLatch> waitForSeqAckLatch=new AtomicReference<CountDownLatch>(); private final boolean storeStatistics; - + + private final int chunksize; + public UDTSender(UDTSession session,UDPEndPoint endpoint){ if(!session.isReady())throw new IllegalStateException("UDTSession is not ready."); this.endpoint= endpoint; this.session=session; statistics=session.getStatistics(); senderLossList=new SenderLossList(); - sendBuffer=new ConcurrentHashMap<Long, DataPacket>(session.getFlowWindowSize(),0.75f,2); - sendQueue = new ArrayBlockingQueue<DataPacket>(session.getFlowWindowSize(), /*fairness*/ true); + sendBuffer=new ConcurrentHashMap<Long, byte[]>(session.getFlowWindowSize(),0.75f,2); + chunksize=session.getDatagramSize()-24;//need space for the header; + flowWindow=new FlowWindow(session.getFlowWindowSize(),chunksize); lastAckSequenceNumber=session.getInitialSequenceNumber(); currentSequenceNumber=session.getInitialSequenceNumber()-1; waitForAckLatch.set(new CountDownLatch(1)); @@ -179,16 +181,14 @@ } }; senderThread=UDTThreadFactory.get().newThread(r); + String s=(session instanceof ServerSession)? "ServerSession": "ClientSession"; + senderThread.setName("UDTSender-"+s+"-"+senderThread.getName()); senderThread.start(); } /** * sends the given data packet, storing the relevant information - * - * @param data - * @throws IOException - * @throws InterruptedException */ private void send(DataPacket p)throws IOException{ synchronized(sendLock){ @@ -203,28 +203,63 @@ throughput.end(); throughput.begin(); } - sendBuffer.put(p.getPacketSequenceNumber(), p); + sendBuffer.put(p.getPacketSequenceNumber(), p.getData()); unacknowledged.incrementAndGet(); } statistics.incNumberOfSentDataPackets(); } + protected void sendUdtPacket(ByteBuffer bb, int timeout, TimeUnit units)throws IOException, InterruptedException{ + if(!started)start(); + DataPacket packet=null; + do{ + packet=flowWindow.getForProducer(); + if(packet==null){ + Thread.sleep(10); + } + }while(packet==null);//TODO check timeout... + try{ + packet.setPacketSequenceNumber(getNextSequenceNumber()); + packet.setSession(session); + packet.setDestinationID(session.getDestination().getSocketID()); + int len=Math.min(bb.remaining(),chunksize); + byte[] data=packet.getData(); + bb.get(data,0,len); + packet.setLength(len); + }finally{ + flowWindow.produce(); + } + + } + /** - * writes a data packet into the sendQueue, waiting at most for the specified time + * writes a data packet, waiting at most for the specified time * if this is not possible due to a full send queue * - * @return <code>true</code>if the packet was added, <code>false</code> if the - * packet could not be added because the queue was full - * @param p * @param timeout * @param units * @return * @throws IOException * @throws InterruptedException */ - protected boolean sendUdtPacket(DataPacket p, int timeout, TimeUnit units)throws IOException,InterruptedException{ + protected void sendUdtPacket(byte[]data, int timeout, TimeUnit units)throws IOException, InterruptedException{ if(!started)start(); - return sendQueue.offer(p,timeout,units); + DataPacket packet=null; + do{ + packet=flowWindow.getForProducer(); + if(packet==null){ + Thread.sleep(10); + // System.out.println("queue full: "+flowWindow); + } + }while(packet==null); + try{ + packet.setPacketSequenceNumber(getNextSequenceNumber()); + packet.setSession(session); + packet.setDestinationID(session.getDestination().getSocketID()); + packet.setData(data); + }finally{ + flowWindow.produce(); + } } //receive a packet from server from the peer @@ -268,6 +303,7 @@ for(long s=lastAckSequenceNumber;s<ackNumber;s++){ synchronized (sendLock) { removed=sendBuffer.remove(s)!=null; + senderLossList.remove(s); } if(removed){ unacknowledged.decrementAndGet(); @@ -291,7 +327,7 @@ session.getCongestionControl().onLoss(nak.getDecodedLossInfo()); session.getSocket().getReceiver().resetEXPTimer(); statistics.incNumberOfNAKReceived(); - + if(logger.isLoggable(Level.FINER)){ logger.finer("NAK for "+nak.getDecodedLossInfo().size()+" packets lost, " +"set send period to "+session.getCongestionControl().getSendInterval()); @@ -322,13 +358,11 @@ public void senderAlgorithm()throws InterruptedException, IOException{ while(!paused){ iterationStart=Util.getCurrentTime(); - //if the sender's loss list is not empty - if (!senderLossList.isEmpty()) { - Long entry=senderLossList.getFirstEntry(); - handleResubmit(entry); + Long entry=senderLossList.getFirstEntry(); + if(entry!=null){ + handleRetransmit(entry); } - else { //if the number of unacknowledged data packets does not exceed the congestion @@ -336,9 +370,9 @@ int unAcknowledged=unacknowledged.get(); if(unAcknowledged<session.getCongestionControl().getCongestionWindowSize() - && unAcknowledged<session.getFlowWindowSize()){ + && unAcknowledged<session.getFlowWindowSize()){ //check for application data - DataPacket dp=sendQueue.poll(); + DataPacket dp=flowWindow.consumeData(); if(dp!=null){ send(dp); largestSentSequenceNumber=dp.getPacketSequenceNumber(); @@ -374,15 +408,21 @@ } /** - * re-submits an entry from the sender loss list + * re-transmit an entry from the sender loss list * @param entry */ - protected void handleResubmit(Long seqNumber){ + protected void handleRetransmit(Long seqNumber){ try { //retransmit the packet and remove it from the list - DataPacket pktToRetransmit = sendBuffer.get(seqNumber); - if(pktToRetransmit!=null){ - endpoint.doSend(pktToRetransmit); + byte[]data=sendBuffer.get(seqNumber); + if(data!=null){ + //System.out.println("re-transmit "+data); + DataPacket packet=new DataPacket(); + packet.setPacketSequenceNumber(seqNumber); + packet.setSession(session); + packet.setDestinationID(session.getDestination().getSocketID()); + packet.setData(data); + endpoint.doSend(packet); statistics.incNumberOfRetransmittedDataPackets(); } }catch (Exception e) { @@ -457,14 +497,14 @@ */ public void waitForAck()throws InterruptedException{ waitForAckLatch.set(new CountDownLatch(1)); - waitForAckLatch.get().await(2, TimeUnit.MILLISECONDS); + waitForAckLatch.get().await(200, TimeUnit.MICROSECONDS); } public void stop(){ stopped=true; } - + public void pause(){ startLatch=new CountDownLatch(1); paused=true; Modified: udt-java/trunk/src/main/java/udt/UDTSession.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSession.java 2011-01-06 16:13:32 UTC (rev 53) +++ udt-java/trunk/src/main/java/udt/UDTSession.java 2011-02-17 21:24:32 UTC (rev 54) @@ -74,7 +74,7 @@ * flow window size, i.e. how many data packets are * in-flight at a single time */ - protected int flowWindowSize=1024; + protected int flowWindowSize=1024*10; /** * remote UDT entity (address and socket ID) Modified: udt-java/trunk/src/main/java/udt/UDTSocket.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSocket.java 2011-01-06 16:13:32 UTC (rev 53) +++ udt-java/trunk/src/main/java/udt/UDTSocket.java 2011-02-17 21:24:32 UTC (rev 54) @@ -36,46 +36,41 @@ import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.util.concurrent.TimeUnit; - -import udt.packets.DataPacket; - /** * UDTSocket is analogous to a normal java.net.Socket, it provides input and * output streams for the application * * TODO is it possible to actually extend java.net.Socket ? * - * */ public class UDTSocket { - + //endpoint private final UDPEndPoint endpoint; - + private volatile boolean active; - - //processing received data + + //processing received data private UDTReceiver receiver; private UDTSender sender; - + private final UDTSession session; private UDTInputStream inputStream; private UDTOutputStream outputStream; - /** - * @param host - * @param port - * @param endpoint - * @throws SocketException,UnknownHostException - */ + * @param host + * @param port + * @param endpoint + * @throws SocketException,UnknownHostException + */ public UDTSocket(UDPEndPoint endpoint, UDTSession session)throws SocketException,UnknownHostException{ this.endpoint=endpoint; this.session=session; this.receiver=new UDTReceiver(session,endpoint); this.sender=new UDTSender(session,endpoint); } - + public UDTReceiver getReceiver() { return receiver; } @@ -114,7 +109,7 @@ } return inputStream; } - + /** * get the output stream for writing to this socket * @return @@ -125,20 +120,20 @@ } return outputStream; } - + public final UDTSession getSession(){ return session; } - + /** * write single block of data without waiting for any acknowledgement * @param data */ protected void doWrite(byte[]data)throws IOException{ doWrite(data, 0, data.length); - + } - + /** * write the given data * @param data - the data array @@ -148,14 +143,14 @@ */ protected void doWrite(byte[]data, int offset, int length)throws IOException{ try{ - doWrite(data, offset, length, Integer.MAX_VALUE, TimeUnit.MILLISECONDS); + doWrite(data, offset, length, 10, TimeUnit.MILLISECONDS); }catch(InterruptedException ie){ IOException io=new IOException(); io.initCause(ie); throw io; } } - + /** * write the given data, waiting at most for the specified time if the queue is full * @param data @@ -167,26 +162,17 @@ * @throws InterruptedException */ protected void doWrite(byte[]data, int offset, int length, int timeout, TimeUnit units)throws IOException,InterruptedException{ - int chunksize=session.getDatagramSize()-24;//need some bytes for the header ByteBuffer bb=ByteBuffer.wrap(data,offset,length); - long seqNo=0; while(bb.remaining()>0){ - int len=Math.min(bb.remaining(),chunksize); - byte[]chunk=new byte[len]; - bb.get(chunk); - DataPacket packet=new DataPacket(); - seqNo=sender.getNextSequenceNumber(); - packet.setPacketSequenceNumber(seqNo); - packet.setSession(session); - packet.setDestinationID(session.getDestination().getSocketID()); - packet.setData(chunk); - //put the packet into the send queue - if(!sender.sendUdtPacket(packet, timeout, units)){ - throw new IOException("Queue full"); + try{ + sender.sendUdtPacket(bb, timeout, units); + }catch(Exception ex){ + ex.printStackTrace(); } } if(length>0)active=true; } + /** * will block until the outstanding packets have really been sent out * and acknowledged @@ -207,13 +193,13 @@ //TODO need to check if we can pause the sender... //sender.pause(); } - + //writes and wait for ack protected void doWriteBlocking(byte[]data)throws IOException, InterruptedException{ doWrite(data); flush(); } - + /** * close the connection * @throws IOException Modified: udt-java/trunk/src/main/java/udt/packets/DataPacket.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/DataPacket.java 2011-01-06 16:13:32 UTC (rev 53) +++ udt-java/trunk/src/main/java/udt/packets/DataPacket.java 2011-02-17 21:24:32 UTC (rev 54) @@ -44,12 +44,15 @@ private long destinationID; private UDTSession session; + + private int dataLength; public DataPacket(){ } /** - * create a DataPacket + * create a DataPacket from the given raw data + * * @param encodedData - network data */ public DataPacket(byte[] encodedData){ @@ -58,6 +61,7 @@ public DataPacket(byte[] encodedData, int length){ decode(encodedData,length); + dataLength=length; } void decode(byte[]encodedData,int length){ @@ -75,16 +79,16 @@ } public double getLength(){ - return data.length; + return dataLength; } - /* - * aplivation data - * @param - */ - + public void setLength(int length){ + dataLength=length; + } + public void setData(byte[] data) { this.data = data; + dataLength=data.length; } public long getPacketSequenceNumber() { @@ -125,12 +129,12 @@ */ public byte[] getEncoded(){ //header.length is 16 - byte[] result=new byte[16+data.length]; + byte[] result=new byte[16+dataLength]; System.arraycopy(PacketUtil.encode(packetSequenceNumber), 0, result, 0, 4); System.arraycopy(PacketUtil.encode(messageNumber), 0, result, 4, 4); System.arraycopy(PacketUtil.encode(timeStamp), 0, result, 8, 4); System.arraycopy(PacketUtil.encode(destinationID), 0, result, 12, 4); - System.arraycopy(data, 0, result, 16, data.length); + System.arraycopy(data, 0, result, 16, dataLength); return result; } Modified: udt-java/trunk/src/main/java/udt/receiver/PacketHistoryWindow.java =================================================================== --- udt-java/trunk/src/main/java/udt/receiver/PacketHistoryWindow.java 2011-01-06 16:13:32 UTC (rev 53) +++ udt-java/trunk/src/main/java/udt/receiver/PacketHistoryWindow.java 2011-02-17 21:24:32 UTC (rev 54) @@ -39,12 +39,17 @@ */ public class PacketHistoryWindow extends CircularArray<Long>{ + private final long[]intervals; + private final int num; + /** * create a new PacketHistoryWindow of the given size * @param size */ public PacketHistoryWindow(int size){ super(size); + num=max-1; + intervals=new long[num]; } /** @@ -54,12 +59,11 @@ */ public long getPacketArrivalSpeed(){ if(!haveOverflow)return 0; - int num=max-1; + double AI; double medianPacketArrivalSpeed; double total=0; int count=0; - long[]intervals=new long[num]; int pos=position-1; if(pos<0)pos=num; do{ Added: udt-java/trunk/src/main/java/udt/sender/FlowWindow.java =================================================================== --- udt-java/trunk/src/main/java/udt/sender/FlowWindow.java (rev 0) +++ udt-java/trunk/src/main/java/udt/sender/FlowWindow.java 2011-02-17 21:24:32 UTC (rev 54) @@ -0,0 +1,139 @@ +package udt.sender; + +import java.util.concurrent.locks.ReentrantLock; + +import udt.packets.DataPacket; + +/** + * + * holds a fixed number of {@link DataPacket} instances which are sent out. + * + * it is assumed that a single thread stores new data, and another single thread + * reads/removes data + * + * @author schuller + */ +public class FlowWindow { + + private final DataPacket[]packets; + + private final int length; + + private volatile boolean isEmpty=true; + + private volatile boolean isFull=false; + + private volatile int validEntries=0; + + private volatile boolean isCheckout=false; + + private volatile int writePos=0; + + private volatile int readPos=-1; + + private volatile int consumed=0; + + private volatile int produced=0; + + private final ReentrantLock lock; + + /** + * @param size - flow window size + * @param chunksize - data chunk size + */ + public FlowWindow(int size, int chunksize){ + this.length=size; + packets=new DataPacket[length]; + for(int i=0;i<packets.length;i++){ + packets[i]=new DataPacket(); + packets[i].setData(new byte[chunksize]); + } + lock=new ReentrantLock(true); + } + + /** + * get a data packet for updating with new data + * + * @return <code>null</code> if flow window is full + */ + public DataPacket getForProducer(){ + lock.lock(); + try{ + if(isFull){ + return null; + } + if(isCheckout)throw new IllegalStateException(); + isCheckout=true; + DataPacket p=packets[writePos]; + return p; + }finally{ + lock.unlock(); + } + } + + public void produce(){ + lock.lock(); + try{ + isCheckout=false; + writePos++; + if(writePos==length)writePos=0; + validEntries++; + isFull=validEntries==length-1; + isEmpty=false; + produced++; + }finally{ + lock.unlock(); + } + } + + + public DataPacket consumeData(){ + if(isEmpty){ + return null; + } + lock.lock(); + try{ + readPos++; + DataPacket p=packets[readPos]; + if(readPos==length-1)readPos=-1; + validEntries--; + isEmpty=validEntries==0; + isFull=false; + consumed++; + return p; + }finally{ + lock.unlock(); + } + } + + boolean isEmpty(){ + return isEmpty; + } + + /** + * check if another entry can be added + * @return + */ + public boolean isFull(){ + return isFull; + } + + int readPos(){ + return readPos; + } + + int writePos(){ + return writePos; + } + + int consumed(){ + return consumed; + } + public String toString(){ + StringBuilder sb=new StringBuilder(); + sb.append("FlowWindow size=").append(length); + sb.append(" full=").append(isFull).append(" empty=").append(isEmpty); + sb.append(" consumed=").append(consumed).append(" produced=").append(produced); + return sb.toString(); + } +} Property changes on: udt-java/trunk/src/main/java/udt/sender/FlowWindow.java ___________________________________________________________________ Added: svn:mime-type + text/plain Modified: udt-java/trunk/src/main/java/udt/sender/SenderLossList.java =================================================================== --- udt-java/trunk/src/main/java/udt/sender/SenderLossList.java 2011-01-06 16:13:32 UTC (rev 53) +++ udt-java/trunk/src/main/java/udt/sender/SenderLossList.java 2011-02-17 21:24:32 UTC (rev 54) @@ -33,8 +33,6 @@ package udt.sender; import java.util.LinkedList; -import udt.util.MeanValue; - /** * stores the sequence number of the lost packets in increasing order */ @@ -57,14 +55,19 @@ backingList.add(i,obj); return; } - else if(obj==entry)return; + else if(obj.equals(entry))return; } backingList.add(obj); } } + public void remove(Long obj){ + synchronized (backingList) { + backingList.remove(obj); + } + } /** - * retrieves the loss list entry with the lowest sequence number + * retrieves the loss list entry with the lowest sequence number, or <code>null</code> if loss list is empty */ public Long getFirstEntry(){ synchronized(backingList){ Modified: udt-java/trunk/src/main/java/udt/util/ReceiveFile.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/ReceiveFile.java 2011-01-06 16:13:32 UTC (rev 53) +++ udt-java/trunk/src/main/java/udt/util/ReceiveFile.java 2011-02-17 21:24:32 UTC (rev 54) @@ -109,7 +109,6 @@ while(true)Thread.sleep(10000); } - File file=new File(new String(localFile)); System.out.println("[ReceiveFile] Write to local file <"+file.getAbsolutePath()+">"); FileOutputStream fos=new FileOutputStream(file); Modified: udt-java/trunk/src/main/java/udt/util/UDTStatistics.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/UDTStatistics.java 2011-01-06 16:13:32 UTC (rev 53) +++ udt-java/trunk/src/main/java/udt/util/UDTStatistics.java 2011-02-17 21:24:32 UTC (rev 54) @@ -188,7 +188,7 @@ sb.append("Duplicate data packets: ").append(getNumberOfDuplicateDataPackets()).append("\n"); sb.append("ACK received: ").append(getNumberOfACKReceived()).append("\n"); sb.append("NAK received: ").append(getNumberOfNAKReceived()).append("\n"); - sb.append("Retransmitted data: ").append(getNumberOfNAKReceived()).append("\n"); + sb.append("Retransmitted data: ").append(getNumberOfRetransmittedDataPackets()).append("\n"); sb.append("NAK sent: ").append(getNumberOfNAKSent()).append("\n"); sb.append("ACK sent: ").append(getNumberOfACKSent()).append("\n"); if(roundTripTime>0){ Modified: udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2011-01-06 16:13:32 UTC (rev 53) +++ udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2011-02-17 21:24:32 UTC (rev 54) @@ -21,7 +21,7 @@ boolean running=false; //how many - int num_packets=300; + int num_packets=100; //how large is a single packet int size=1*1024*1024; @@ -55,7 +55,7 @@ new Random().nextBytes(data); MessageDigest digest=MessageDigest.getInstance("MD5"); - while(!serverRunning)Thread.sleep(100); + while(!serverStarted)Thread.sleep(100); long start=System.currentTimeMillis(); System.out.println("Sending <"+num_packets+"> packets of <"+format.format(size/1024.0/1024.0)+"> Mbytes each"); long end=0; @@ -101,6 +101,7 @@ long total=0; volatile boolean serverRunning=true; + volatile boolean serverStarted=false; volatile String md5_received=null; @@ -110,6 +111,7 @@ Runnable serverProcess=new Runnable(){ public void run(){ + try{ Boolean devNull=Boolean.getBoolean("udt.dev.null"); if(devNull){ @@ -118,6 +120,7 @@ MessageDigest md5=MessageDigest.getInstance("MD5"); long start=System.currentTimeMillis(); UDTSocket s=serverSocket.accept(); + serverStarted=true; assertNotNull(s); UDTInputStream is=s.getInputStream(); byte[]buf=new byte[READ_BUFFERSIZE]; Added: udt-java/trunk/src/test/java/udt/sender/TestFlowWindow.java =================================================================== --- udt-java/trunk/src/test/java/udt/sender/TestFlowWindow.java (rev 0) +++ udt-java/trunk/src/test/java/udt/sender/TestFlowWindow.java 2011-02-17 21:24:32 UTC (rev 54) @@ -0,0 +1,151 @@ +package udt.sender; + +import java.util.concurrent.TimeoutException; + +import junit.framework.TestCase; +import udt.packets.DataPacket; + +public class TestFlowWindow extends TestCase { + + public void testFillWindow()throws InterruptedException, TimeoutException{ + FlowWindow fw=new FlowWindow(3, 128); + DataPacket p1=fw.getForProducer(); + assertNotNull(p1); + fw.produce(); + DataPacket p2=fw.getForProducer(); + assertNotNull(p2); + fw.produce(); + assertFalse(p1==p2); + DataPacket p3=fw.getForProducer(); + assertNotNull(p3); + assertFalse(p1==p3); + assertFalse(p2==p3); + fw.produce(); + assertTrue(fw.isFull()); + + DataPacket no=fw.getForProducer(); + assertNull("Window should be full",no); + + DataPacket c1=fw.consumeData(); + //must be p1 + assertTrue(c1==p1); + DataPacket c2=fw.consumeData(); + //must be p2 + assertTrue(c2==p2); + DataPacket c3=fw.consumeData(); + //must be p3 + assertTrue(c3==p3); + assertTrue(fw.isEmpty()); + } + + public void testOverflow()throws InterruptedException, TimeoutException{ + FlowWindow fw=new FlowWindow(3, 64); + DataPacket p1=fw.getForProducer(); + assertNotNull(p1); + fw.produce(); + DataPacket p2=fw.getForProducer(); + assertNotNull(p2); + fw.produce(); + assertFalse(p1==p2); + DataPacket p3=fw.getForProducer(); + assertNotNull(p3); + assertFalse(p1==p3); + assertFalse(p2==p3); + fw.produce(); + assertTrue(fw.isFull()); + + //read one + DataPacket c1=fw.consumeData(); + //must be p1 + assertTrue(c1==p1); + assertFalse(fw.isFull()); + + //now a slot for writing should be free again + DataPacket p4=fw.getForProducer(); + assertNotNull(p4); + fw.produce(); + //which is again p1 + assertTrue(p4==p1); + + } + + private volatile boolean fail=false; + + public void testConcurrentReadWrite()throws InterruptedException{ + final FlowWindow fw=new FlowWindow(20, 64); + Thread reader=new Thread(new Runnable(){ + public void run(){ + doRead(fw); + } + }); + reader.setName("reader"); + Thread writer=new Thread(new Runnable(){ + public void run(){ + doWrite(fw); + } + }); + writer.setName("writer"); + + writer.start(); + reader.start(); + + int c=0; + while(read && write && c<10){ + Thread.sleep(1000); + c++; + } + assertFalse("An error occured in reader or writer",fail); + + } + + volatile boolean read=true; + volatile boolean write=true; + int N=100000; + + private void doRead(final FlowWindow fw){ + System.out.println("Starting reader..."); + try{ + for(int i=0;i<N;i++){ + DataPacket p=null; + while( (p=fw.consumeData())==null){ + Thread.sleep(1); + } + synchronized (p) { + assertEquals(i,p.getMessageNumber()); + } + } + }catch(Throwable ex){ + ex.printStackTrace(); + fail=true; + } + System.out.println("Exiting reader..."); + read=false; + } + + private void doWrite(final FlowWindow fw){ + System.out.println("Starting writer..."); + DataPacket p=null; + try{ + for(int i=0;i<N;i++){ + p=null; + do{ + p=fw.getForProducer(); + if(p!=null){ + synchronized(p){ + p.setData(("test"+i).getBytes()); + p.setMessageNumber(i); + fw.produce(); + } + } + }while(p==null); + } + }catch(Exception ex){ + ex.printStackTrace(); + System.out.println("ERROR****"); + fail=true; + } + System.out.println("Exiting writer..."); + write=false; + } + +} Property changes on: udt-java/trunk/src/test/java/udt/sender/TestFlowWindow.java ___________________________________________________________________ Added: svn:mime-type + text/plain This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2011-08-16 17:56:14
|
Revision: 64 http://udt-java.svn.sourceforge.net/udt-java/?rev=64&view=rev Author: bschuller Date: 2011-08-16 17:56:07 +0000 (Tue, 16 Aug 2011) Log Message: ----------- fix two bugs: thanks to ajsenf (Alexander Senf) see https://sourceforge.net/projects/udt-java/forums/forum/1109269/topic/4615162?message=10597365 Modified Paths: -------------- udt-java/trunk/src/main/java/udt/UDTClient.java udt-java/trunk/src/main/java/udt/UDTSender.java udt-java/trunk/src/main/java/udt/packets/Acknowledgment2.java udt-java/trunk/src/main/java/udt/util/ReceiveBuffer.java udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java Modified: udt-java/trunk/src/main/java/udt/UDTClient.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTClient.java 2011-08-13 00:24:18 UTC (rev 63) +++ udt-java/trunk/src/main/java/udt/UDTClient.java 2011-08-16 17:56:07 UTC (rev 64) @@ -36,6 +36,7 @@ import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; +import java.util.concurrent.TimeoutException; import java.util.logging.Level; import java.util.logging.Logger; @@ -115,15 +116,15 @@ } /** - * flush outstanding data (and make sure it is acknowledged) + * flush outstanding data, with the specified maximum waiting time + * @param timeOut - timeout in millis (if smaller than 0, no timeout is used) * @throws IOException * @throws InterruptedException */ - public void flush()throws IOException, InterruptedException{ + public void flush()throws IOException, InterruptedException, TimeoutException{ clientSession.getSocket().flush(); } - public void shutdown()throws IOException{ if (clientSession.isReady()&& clientSession.active==true) Modified: udt-java/trunk/src/main/java/udt/UDTSender.java =================================================================== --- udt-java/trunk/src/main/java/udt/UDTSender.java 2011-08-13 00:24:18 UTC (rev 63) +++ udt-java/trunk/src/main/java/udt/UDTSender.java 2011-08-16 17:56:07 UTC (rev 64) @@ -39,7 +39,8 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Level; import java.util.logging.Logger; @@ -110,11 +111,9 @@ private volatile CountDownLatch startLatch=new CountDownLatch(1); //used by the sender to wait for an ACK - private final AtomicReference<CountDownLatch> waitForAckLatch=new AtomicReference<CountDownLatch>(); + private final ReentrantLock ackLock=new ReentrantLock(); + private final Condition ackCondition=ackLock.newCondition(); - //used by the sender to wait for an ACK of a certain sequence number - private final AtomicReference<CountDownLatch> waitForSeqAckLatch=new AtomicReference<CountDownLatch>(); - private final boolean storeStatistics; private final int chunksize; @@ -130,8 +129,6 @@ flowWindow=new FlowWindow(session.getFlowWindowSize(),chunksize); lastAckSequenceNumber=session.getInitialSequenceNumber(); currentSequenceNumber=session.getInitialSequenceNumber()-1; - waitForAckLatch.set(new CountDownLatch(1)); - waitForSeqAckLatch.set(new CountDownLatch(1)); storeStatistics=Boolean.getBoolean("udt.sender.storeStatistics"); initMetrics(); doStart(); @@ -278,8 +275,9 @@ } protected void onAcknowledge(Acknowledgement acknowledgement)throws IOException{ - waitForAckLatch.get().countDown(); - waitForSeqAckLatch.get().countDown(); + ackLock.lock(); + ackCondition.signal(); + ackLock.unlock(); CongestionControl cc=session.getCongestionControl(); long rtt=acknowledgement.getRoundTripTime(); @@ -407,6 +405,8 @@ } } + private final DataPacket retransmit=new DataPacket(); + /** * re-transmit an entry from the sender loss list * @param entry @@ -416,13 +416,11 @@ //retransmit the packet and remove it from the list byte[]data=sendBuffer.get(seqNumber); if(data!=null){ - //System.out.println("re-transmit "+data); - DataPacket packet=new DataPacket(); - packet.setPacketSequenceNumber(seqNumber); - packet.setSession(session); - packet.setDestinationID(session.getDestination().getSocketID()); - packet.setData(data); - endpoint.doSend(packet); + retransmit.setPacketSequenceNumber(seqNumber); + retransmit.setSession(session); + retransmit.setDestinationID(session.getDestination().getSocketID()); + retransmit.setData(data); + endpoint.doSend(retransmit); statistics.incNumberOfRetransmittedDataPackets(); } }catch (Exception e) { @@ -486,18 +484,37 @@ */ public void waitForAck(long sequenceNumber)throws InterruptedException{ while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ - waitForSeqAckLatch.set(new CountDownLatch(1)); - waitForSeqAckLatch.get().await(10, TimeUnit.MILLISECONDS); + ackLock.lock(); + try{ + ackCondition.await(100, TimeUnit.MICROSECONDS); + }finally{ + ackLock.unlock(); + } } } + public void waitForAck(long sequenceNumber, int timeout)throws InterruptedException{ + while(!session.isShutdown() && !haveAcknowledgementFor(sequenceNumber)){ + ackLock.lock(); + try{ + ackCondition.await(timeout, TimeUnit.MILLISECONDS); + }finally{ + ackLock.unlock(); + } + } + } + /** * wait for the next acknowledge * @throws InterruptedException */ public void waitForAck()throws InterruptedException{ - waitForAckLatch.set(new CountDownLatch(1)); - waitForAckLatch.get().await(200, TimeUnit.MICROSECONDS); + ackLock.lock(); + try{ + ackCondition.await(200, TimeUnit.MICROSECONDS); + }finally{ + ackLock.unlock(); + } } Modified: udt-java/trunk/src/main/java/udt/packets/Acknowledgment2.java =================================================================== --- udt-java/trunk/src/main/java/udt/packets/Acknowledgment2.java 2011-08-13 00:24:18 UTC (rev 63) +++ udt-java/trunk/src/main/java/udt/packets/Acknowledgment2.java 2011-08-16 17:56:07 UTC (rev 64) @@ -61,16 +61,16 @@ } void decode(byte[]data){ + ackSequenceNumber=PacketUtil.decode(data, 0); } public boolean forSender(){ return false; } - private static final byte[]empty=new byte[0]; @Override public byte[] encodeControlInformation(){ - return empty; + return PacketUtil.encode(ackSequenceNumber); } } Modified: udt-java/trunk/src/main/java/udt/util/ReceiveBuffer.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/ReceiveBuffer.java 2011-08-13 00:24:18 UTC (rev 63) +++ udt-java/trunk/src/main/java/udt/util/ReceiveBuffer.java 2011-08-16 17:56:07 UTC (rev 64) @@ -54,7 +54,7 @@ try{ long seq=data.getSequenceNumber(); //if already have this chunk, discard it - if(SequenceNumber.compare(seq, initialSequenceNumber)<0)return true; + if(SequenceNumber.compare(seq, highestReadSequenceNumber)<=0)return true; //else compute insert position int offset=(int)SequenceNumber.seqOffset(initialSequenceNumber, seq); int insert=offset% size; @@ -120,6 +120,7 @@ } else return null; } + numValidChunks.decrementAndGet(); return r; } Modified: udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2011-08-13 00:24:18 UTC (rev 63) +++ udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2011-08-16 17:56:07 UTC (rev 64) @@ -5,6 +5,7 @@ import java.security.MessageDigest; import java.text.NumberFormat; import java.util.Random; +import java.util.concurrent.TimeoutException; import java.util.logging.Level; import java.util.logging.Logger; @@ -21,10 +22,10 @@ boolean running=false; //how many - int num_packets=100; + int num_packets=500; //how large is a single packet - int size=1*1024*1024; + int size=20*1024*1024; int TIMEOUT=Integer.MAX_VALUE; @@ -36,7 +37,12 @@ // System.setProperty("udt.sender.storeStatistics","true"); UDTReceiver.dropRate=0; TIMEOUT=Integer.MAX_VALUE; - doTest(); + try{ + doTest(); + }catch(TimeoutException te){ + te.printStackTrace(); + fail(); + } } private final NumberFormat format=NumberFormat.getNumberInstance(); @@ -59,6 +65,7 @@ long start=System.currentTimeMillis(); System.out.println("Sending <"+num_packets+"> packets of <"+format.format(size/1024.0/1024.0)+"> Mbytes each"); long end=0; + if(serverRunning){ for(int i=0;i<num_packets;i++){ long block=System.currentTimeMillis(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2011-12-01 19:52:58
|
Revision: 68 http://udt-java.svn.sourceforge.net/udt-java/?rev=68&view=rev Author: bschuller Date: 2011-12-01 19:52:51 +0000 (Thu, 01 Dec 2011) Log Message: ----------- apply a few fixes from P. Elgee Modified Paths: -------------- udt-java/trunk/src/main/java/udt/sender/FlowWindow.java udt-java/trunk/src/main/java/udt/util/ReceiveBuffer.java udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java udt-java/trunk/src/test/java/udt/sender/TestFlowWindow.java Modified: udt-java/trunk/src/main/java/udt/sender/FlowWindow.java =================================================================== --- udt-java/trunk/src/main/java/udt/sender/FlowWindow.java 2011-12-01 13:55:08 UTC (rev 67) +++ udt-java/trunk/src/main/java/udt/sender/FlowWindow.java 2011-12-01 19:52:51 UTC (rev 68) @@ -78,7 +78,7 @@ writePos++; if(writePos==length)writePos=0; validEntries++; - isFull=validEntries==length-1; + isFull=validEntries==length; isEmpty=false; produced++; }finally{ Modified: udt-java/trunk/src/main/java/udt/util/ReceiveBuffer.java =================================================================== --- udt-java/trunk/src/main/java/udt/util/ReceiveBuffer.java 2011-12-01 13:55:08 UTC (rev 67) +++ udt-java/trunk/src/main/java/udt/util/ReceiveBuffer.java 2011-12-01 19:52:51 UTC (rev 68) @@ -120,7 +120,6 @@ } else return null; } - numValidChunks.decrementAndGet(); return r; } Modified: udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2011-12-01 13:55:08 UTC (rev 67) +++ udt-java/trunk/src/test/java/udt/performance/TestUDTLargeData.java 2011-12-01 19:52:51 UTC (rev 68) @@ -22,7 +22,7 @@ boolean running=false; //how many - int num_packets=500; + int num_packets=50; //how large is a single packet int size=20*1024*1024; Modified: udt-java/trunk/src/test/java/udt/sender/TestFlowWindow.java =================================================================== --- udt-java/trunk/src/test/java/udt/sender/TestFlowWindow.java 2011-12-01 13:55:08 UTC (rev 67) +++ udt-java/trunk/src/test/java/udt/sender/TestFlowWindow.java 2011-12-01 19:52:51 UTC (rev 68) @@ -110,9 +110,7 @@ while( (p=fw.consumeData())==null){ Thread.sleep(1); } - synchronized (p) { - assertEquals(i,p.getMessageNumber()); - } + assertEquals(i,p.getMessageNumber()); } }catch(Throwable ex){ ex.printStackTrace(); @@ -131,11 +129,9 @@ do{ p=fw.getForProducer(); if(p!=null){ - synchronized(p){ - p.setData(("test"+i).getBytes()); - p.setMessageNumber(i); - fw.produce(); - } + p.setData(("test"+i).getBytes()); + p.setMessageNumber(i); + fw.produce(); } }while(p==null); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bsc...@us...> - 2012-02-03 09:09:43
|
Revision: 70 http://udt-java.svn.sourceforge.net/udt-java/?rev=70&view=rev Author: bschuller Date: 2012-02-03 09:09:37 +0000 (Fri, 03 Feb 2012) Log Message: ----------- roll back change to FlowWindow; add some comments to make it easier to understand Modified Paths: -------------- udt-java/trunk/src/main/java/udt/sender/FlowWindow.java udt-java/trunk/src/test/java/udt/TestUDTServerSocket.java udt-java/trunk/src/test/java/udt/performance/UDPTest.java udt-java/trunk/src/test/java/udt/sender/TestFlowWindow.java Modified: udt-java/trunk/src/main/java/udt/sender/FlowWindow.java =================================================================== --- udt-java/trunk/src/main/java/udt/sender/FlowWindow.java 2012-02-03 06:57:00 UTC (rev 69) +++ udt-java/trunk/src/main/java/udt/sender/FlowWindow.java 2012-02-03 09:09:37 UTC (rev 70) @@ -6,10 +6,12 @@ /** * - * holds a fixed number of {@link DataPacket} instances which are sent out. + * Holds a fixed number of {@link DataPacket} instances which are sent out.<br/> * - * it is assumed that a single thread stores new data, and another single thread - * reads/removes data + * it is assumed that a single thread (the producer) stores new data, + * and another single thread (the consumer) reads/removes data.<br/> + * + * * * @author schuller */ @@ -23,12 +25,15 @@ private volatile boolean isFull=false; + //valid entries that can be read private volatile int validEntries=0; private volatile boolean isCheckout=false; + //index where the next data packet will be written to private volatile int writePos=0; + //one before the index where the next data packet will be read from private volatile int readPos=-1; private volatile int consumed=0; @@ -42,7 +47,7 @@ * @param chunksize - data chunk size */ public FlowWindow(int size, int chunksize){ - this.length=size; + this.length=size+1; packets=new DataPacket[length]; for(int i=0;i<packets.length;i++){ packets[i]=new DataPacket(); @@ -64,21 +69,25 @@ } if(isCheckout)throw new IllegalStateException(); isCheckout=true; - DataPacket p=packets[writePos]; - return p; + return packets[writePos]; }finally{ lock.unlock(); } } + /** + * notify the flow window that the data packet obtained by {@link #getForProducer()} + * has been filled with data and is ready for sending out + */ public void produce(){ lock.lock(); try{ + if(!isCheckout)throw new IllegalStateException(); isCheckout=false; writePos++; if(writePos==length)writePos=0; validEntries++; - isFull=validEntries==length; + isFull=validEntries==length-1; isEmpty=false; produced++; }finally{ @@ -88,11 +97,11 @@ public DataPacket consumeData(){ - if(isEmpty){ - return null; - } lock.lock(); try{ + if(isEmpty){ + return null; + } readPos++; DataPacket p=packets[readPos]; if(readPos==length-1)readPos=-1; @@ -133,6 +142,7 @@ StringBuilder sb=new StringBuilder(); sb.append("FlowWindow size=").append(length); sb.append(" full=").append(isFull).append(" empty=").append(isEmpty); + sb.append(" readPos=").append(readPos).append(" writePos=").append(writePos); sb.append(" consumed=").append(consumed).append(" produced=").append(produced); return sb.toString(); } Modified: udt-java/trunk/src/test/java/udt/TestUDTServerSocket.java =================================================================== --- udt-java/trunk/src/test/java/udt/TestUDTServerSocket.java 2012-02-03 06:57:00 UTC (rev 69) +++ udt-java/trunk/src/test/java/udt/TestUDTServerSocket.java 2012-02-03 09:09:37 UTC (rev 70) @@ -25,9 +25,9 @@ @Test public void testWithoutLoss()throws Exception{ - Logger.getLogger("udt").setLevel(Level.WARNING); + Logger.getLogger("udt").setLevel(Level.INFO); UDTReceiver.dropRate=0; - num_packets=640; + num_packets=1000; TIMEOUT=Integer.MAX_VALUE; doTest(); } @@ -37,9 +37,9 @@ public void testWithLoss()throws Exception{ UDTReceiver.dropRate=3; TIMEOUT=Integer.MAX_VALUE; - num_packets=512; + num_packets=100; //set log level - Logger.getLogger("udt").setLevel(Level.WARNING); + Logger.getLogger("udt").setLevel(Level.INFO); doTest(); } @@ -48,9 +48,9 @@ public void testLargeDataSet()throws Exception{ UDTReceiver.dropRate=0; TIMEOUT=Integer.MAX_VALUE; - num_packets=3*1024; + num_packets=100; //set log level - Logger.getLogger("udt").setLevel(Level.WARNING); + Logger.getLogger("udt").setLevel(Level.INFO); doTest(); } Modified: udt-java/trunk/src/test/java/udt/performance/UDPTest.java =================================================================== --- udt-java/trunk/src/test/java/udt/performance/UDPTest.java 2012-02-03 06:57:00 UTC (rev 69) +++ udt-java/trunk/src/test/java/udt/performance/UDPTest.java 2012-02-03 09:09:37 UTC (rev 70) @@ -6,6 +6,7 @@ import java.util.Random; import java.util.concurrent.BlockingQueue; import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.TimeUnit; import org.junit.Test; @@ -18,7 +19,7 @@ */ public class UDPTest { - final int num_packets=10*10*1000; + final int num_packets=1000; final int packetSize=UDPEndPoint.DATAGRAM_SIZE; @Test @@ -48,6 +49,7 @@ dgSendInterval.end(); dgSendTime.begin(); s.send(dp); + Thread.sleep(5); dgSendTime.end(); dgSendInterval.begin(); } @@ -76,11 +78,10 @@ public void run(){ try{ byte[]buf=new byte[packetSize]; - DatagramPacket dp=new DatagramPacket(buf,buf.length); while(true){ + DatagramPacket dp=new DatagramPacket(buf,buf.length); serverSocket.receive(dp); handoff.offer(dp); - total+=dp.getLength(); } } catch(Exception e){ @@ -91,6 +92,7 @@ }; Thread t=new Thread(serverProcess); t.start(); + System.out.println("Server started."); } private final BlockingQueue<DatagramPacket> handoff=new SynchronousQueue<DatagramPacket>(); @@ -99,11 +101,15 @@ Runnable serverProcess=new Runnable(){ public void run(){ try{ + int counter=0; long start=System.currentTimeMillis(); - while(true){ - DatagramPacket dp=handoff.poll(); - if(dp!=null)total+=dp.getLength(); - if(total==N)break; + while(counter<num_packets){ + DatagramPacket dp=handoff.poll(10, TimeUnit.MILLISECONDS); + if(dp!=null){ + total+=dp.getLength(); + counter++; + System.out.println("Count: "+counter); + } } long end=System.currentTimeMillis(); System.out.println("Server time: "+(end-start)+" ms."); @@ -117,6 +123,7 @@ }; Thread t=new Thread(serverProcess); t.start(); + System.out.println("Hand-off thread started."); } Modified: udt-java/trunk/src/test/java/udt/sender/TestFlowWindow.java =================================================================== --- udt-java/trunk/src/test/java/udt/sender/TestFlowWindow.java 2012-02-03 06:57:00 UTC (rev 69) +++ udt-java/trunk/src/test/java/udt/sender/TestFlowWindow.java 2012-02-03 09:09:37 UTC (rev 70) @@ -33,6 +33,7 @@ DataPacket no=fw.getForProducer(); assertNull("Window should be full",no); + assertTrue(fw.isFull()); DataPacket c1=fw.consumeData(); //must be p1 @@ -73,14 +74,21 @@ DataPacket p4=fw.getForProducer(); assertNotNull(p4); fw.produce(); + fw.consumeData(); + + DataPacket p5=fw.getForProducer(); + assertNotNull(p5); + fw.produce(); + //which is again p1 - assertTrue(p4==p1); + assertTrue(p5==p1); } private volatile boolean fail=false; - public void testConcurrentReadWrite()throws InterruptedException{ + @Test + public void testConcurrentReadWrite_20()throws InterruptedException{ final FlowWindow fw=new FlowWindow(20, 64); Thread reader=new Thread(new Runnable(){ public void run(){ @@ -107,6 +115,34 @@ } + @Test + public void testConcurrentReadWrite_2()throws InterruptedException{ + final FlowWindow fw=new FlowWindow(2, 64); + Thread reader=new Thread(new Runnable(){ + public void run(){ + doRead(fw); + } + }); + reader.setName("reader"); + Thread writer=new Thread(new Runnable(){ + public void run(){ + doWrite(fw); + } + }); + writer.setName("writer"); + + writer.start(); + reader.start(); + + int c=0; + while(read && write && c<10){ + Thread.sleep(1000); + c++; + } + assertFalse("An error occured in reader or writer",fail); + + } + volatile boolean read=true; volatile boolean write=true; int N=100000; @@ -123,6 +159,7 @@ } }catch(Throwable ex){ ex.printStackTrace(); + System.out.println(fw); fail=true; } System.out.println("Exiting reader..."); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |