基于UDP的数据传输协议是一种互联网数据传输协议。UDT的主要目的是支持高速广域网上的海量数据传输,而互联网上的标准数据传输协议TCP在高带宽长距离网络上性能很差,控制UDP的流量和拥塞控制如何解决,请参考下文
 
 

  UDP的概念

  UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规范。UDP在IP报文的协议号是17。

  流量控制

  对于一个带宽1Gbps, RTT为100ms的网络来说

  BDP=1,000,000,000*0.1/8=12,500,000字节=12207K=12M

  传统TCP接收窗口大小=65535byte=64K, 显然满足不了

  udt使用包大小1500byte, 默认接口窗口大小为8192, 因此

  接收窗口的大小为=1500*8192=12,288,000字节=12000K=11.7M

  因此, 可以看到udt的默认设置已经足够.

  Congestion Control(拥塞控制)

  1. 两个重要的参数:

  congestion window size and the inter-packet sending interval

  2. 主要的接口

  1) init: when the UDT socket is connected.

  2) close: when the UDT socket is closed.

  3) onACK: when ACK is received.

  4) onLOSS: when NACK is received.

  5) onTimeout: when timeout occurs.

  6) onPktSent: when a data packet is sent.

  7) onPktRecv: when a data packet is received.

  3. udt的拥塞算法:

  On ACK packet received:

  1) If the current status is in the slow start phase, set the

  congestion window size to the product of packet arrival rate and

  (RTT + SYN). Slow Start ends. Stop.

  2) Set the congestion window size (CWND) to: CWND = A * (RTT + SYN) +16.

  3) The number of sent packets to be increased in the next SYN period

  (inc) is calculated as:

  if (B <= C)

  inc = 1/PS;

  else

  inc = max(10^(ceil(log10((B-C)*PS*8))) * Beta/PS, 1/PS);

  where B is the estimated link capacity and C is the current

  sending speed. All are counted as packets per second. PS is the

  fixed size of UDT packet counted in bytes. Beta is a constant

  value of 0.0000015.

  4) The SND period is updated as:

  SND = (SND * SYN) / (SND * inc + SYN).

  Java代码

 

复制代码
代码如下:
<strong>  </strong>1.Java代码
  2.*/
  3.publicvoidonACK(longackSeqno){
  4.//increasewindowduringslowstart
  5.if(slowStartPhase){
  6.congestionWindowSize+=ackSeqno-lastAckSeqNumber;
  7.lastAckSeqNumber=ackSeqno;
  8.//butnotbeyondamaximumsize
  9.if(congestionWindowSize>session.getFlowWindowSize()){
  10.slowStartPhase=false;
  11.if(packetArrivalRate>0){
  12.packetSendingPeriod=1000000.0/packetArrivalRate;
  13.}
  14.else{
  15.packetSendingPeriod=(double)congestionWindowSize/(roundTripTime+Util.getSYNTimeD());
  16.}
  17.}
  18.
  19.}else{
  20.//1.ifitisnotinslowstartphase,setthecongestionwindowsize
  21.//totheproductofpacketarrivalrateand(rtt+SYN)
  22.doubleA=packetArrivalRate/1000000.0*(roundTripTime+Util.getSYNTimeD());
  23.congestionWindowSize=(long)A+16;
  24.if(logger.isLoggable(Level.FINER)){
  25.logger.finer("receiverate"+packetArrivalRate+"rtt"+roundTripTime+"settowindowsize:"+(A+16));
  26.}
  27.}
  28.
  29.//norateincreaseduringslowstart
  30.if(slowStartPhase)return;
  31.
  32.//norateincrease"immediately"afteraNAK
  33.if(loss){
  34.loss=false;
  35.return;
  36.}
  37.
  38.//4.computetheincreaseinsentpacketsforthenextSYNperiod
  39.doublenumOfIncreasingPacket=computeNumOfIncreasingPacket();
  40.
  41.//5.updatethesendperiod
  42.doublefactor=Util.getSYNTimeD()/(packetSendingPeriod*numOfIncreasingPacket+Util.getSYNTimeD());
  43.packetSendingPeriod=factor*packetSendingPeriod;
  44.//packetSendingPeriod=0.995*packetSendingPeriod;
  45.
  46.statistics.setSendPeriod(packetSendingPeriod);
  47.}

 

  On NAK packet received:

  1) If it is in slow start phase, set inter-packet interval to

  1/recvrate. Slow start ends. Stop.

  2) If this NAK starts a new congestion period, increase inter-packet

  interval (snd) to snd = snd * 1.125; Update AvgNAKNum, reset

  NAKCount to 1, and compute DecRandom to a random (average

  distribution) number between 1 and AvgNAKNum. Update LastDecSeq.

  Stop.

  3) If DecCount <= 5, and NAKCount == DecCount * DecRandom:

  a. Update SND period: SND = SND * 1.125;

  b. Increase DecCount by 1;

  c. Record the current largest sent sequence number (LastDecSeq).

  Java代码

 

复制代码
代码如下:
  1./*(non-Javadoc)
  2.*@seeudt.CongestionControl#onNAK(java.util.List)
  3.*/
  4.publicvoidonLoss(List<Integer>lossInfo){
  5.loss=true;
  6.longfirstBiggestlossSeqNo=lossInfo.get(0);
  7.nACKCount++;
  8./*1)Ifitisinslowstartphase,setinter-packetintervalto
  9.1/recvrate.Slowstartends.Stop.*/
  10.if(slowStartPhase){
  11.if(packetArrivalRate>0){
  12.packetSendingPeriod=100000.0/packetArrivalRate;
  13.}
  14.else{
  15.packetSendingPeriod=congestionWindowSize/(roundTripTime+Util.getSYNTime());
  16.}
  17.slowStartPhase=false;
  18.return;
  19.}
  20.
  21.longcurrentMaxSequenceNumber=session.getSocket().getSender().getCurrentSequenceNumber();
  22.//2)IfthisNAKstartsanewcongestionepoch
  23.if(firstBiggestlossSeqNo>lastDecreaseSeqNo){
  24.//-increaseinter-packetinterval
  25.packetSendingPeriod=Math.ceil(packetSendingPeriod*1.125);
  26.//-UpdateAvgNAKNum(theaveragenumberofNAKspercongestion)
  27.averageNACKNum=(int)Math.ceil(averageNACKNum*0.875+nACKCount*0.125);
  28.//-resetNAKCountandDecCountto1,
  29.nACKCount=1;
  30.decCount=1;
  31./*-computeDecRandomtoarandom(averagedistribution)numberbetween1andAvgNAKNum*/
  32.decreaseRandom=(int)Math.ceil((averageNACKNum-1)*Math.random()+1);
  33.//-UpdateLastDecSeq
  34.lastDecreaseSeqNo=currentMaxSequenceNumber;
  35.//-Stop.
  36.}
  37.//*3)IfDecCount<=5,andNAKCount==DecCount*DecRandom:
  38.elseif(decCount<=5&&nACKCount==decCount*decreaseRandom){
  39.//a.UpdateSNDperiod:SNDSND=SND*1.125;
  40.packetSendingPeriod=Math.ceil(packetSendingPeriod*1.125);
  41.//b.IncreaseDecCountby1;
  42.decCount++;
  43.//c.Recordthecurrentlargestsentsequencenumber(LastDecSeq).
  44.lastDecreaseSeqNo=currentMaxSequenceNumber;
  45.}
  46.
  47.statistics.setSendPeriod(packetSendingPeriod);
  48.return;
  49.}

 

  以上就是基于UDP传输协议的流量和拥塞控制的代码,希望能帮到大家,谢谢阅读。