rcvbuf.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:5k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * rcvbuf.cc
  3.  * Copyright (C) 2001 by the University of Southern California
  4.  * $Id: rcvbuf.cc,v 1.2 2005/08/25 18:58:08 johnh Exp $
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public License,
  8.  * version 2, as published by the Free Software Foundation.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program; if not, write to the Free Software Foundation, Inc.,
  17.  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  18.  *
  19.  *
  20.  * The copyright of this module includes the following
  21.  * linking-with-specific-other-licenses addition:
  22.  *
  23.  * In addition, as a special exception, the copyright holders of
  24.  * this module give you permission to combine (via static or
  25.  * dynamic linking) this module with free software programs or
  26.  * libraries that are released under the GNU LGPL and with code
  27.  * included in the standard release of ns-2 under the Apache 2.0
  28.  * license or under otherwise-compatible licenses with advertising
  29.  * requirements (or modified versions of such code, with unchanged
  30.  * license).  You may copy and distribute such a system following the
  31.  * terms of the GNU GPL for this module and the licenses of the
  32.  * other code concerned, provided that you include the source code of
  33.  * that other code when and as the GNU GPL requires distribution of
  34.  * source code.
  35.  *
  36.  * Note that people who make modified versions of this module
  37.  * are not obligated to grant this special exception for their
  38.  * modified versions; it is their choice whether to do so.  The GNU
  39.  * General Public License gives permission to release a modified
  40.  * version without this exception; this exception also makes it
  41.  * possible to release a modified version which carries forward this
  42.  * exception.
  43.  *
  44.  */
  45. /*
  46.  * Pragmatic General Multicast (PGM), Reliable Multicast
  47.  * Light-Weight Multicast Services (LMS), Reliable Multicast
  48.  *
  49.  * rcvbuf.cc
  50.  *
  51.  * Utility class used by receivers to provide for packet loss detection,
  52.  * and to compute latency statistics for recovered packets.
  53.  *
  54.  * Christos Papadopoulos
  55.  */
  56. #include "config.h"
  57. #include <stdio.h>
  58. #include "rcvbuf.h"
  59. RcvBuffer::RcvBuffer ()
  60. {
  61. nextpkt_ = 0;
  62. maxpkt_ = -1;
  63. duplicates_ = 0;
  64. delay_sum_ = 0.0;
  65. max_delay_ = 0.0;
  66. min_delay_ = 1e6;
  67. pkts_recovered_ = 0;
  68. tail_ = gap_ = 0;
  69. }
  70. //
  71. // add pkt to buffer with seqno i, received at time tnow
  72. //
  73. void RcvBuffer::add_pkt (int i, double tnow)
  74. {
  75. Gap *g, *pg;
  76. if (exists_pkt (i))
  77. {
  78. duplicates_++;
  79. return;
  80. }
  81. // common case first: got what we expected
  82. if (i == nextpkt_)
  83. {
  84. nextpkt_++;
  85. if (i == maxpkt_ + 1)
  86. maxpkt_++;
  87. return;
  88. }
  89. // new gap
  90. if (i > nextpkt_)
  91. {
  92. g = new Gap;
  93. g->start_ = nextpkt_;
  94. g->end_ = i-1;
  95. g->time_ = tnow;
  96. g->next_ = 0;
  97. if (!gap_)
  98. gap_ = tail_ = g;
  99. else {
  100. tail_->next_ = g;
  101. tail_ = g;
  102. }
  103. nextpkt_ = i+1;
  104. return;
  105. }
  106. // i < nextpkt_ (a retransmission)
  107. pkts_recovered_++;
  108. // is packet part of the first gap?
  109. if (gap_->start_ <= i && i <= gap_->end_)
  110. {
  111. double d = tnow - gap_->time_;
  112. if (d > max_delay_)
  113. max_delay_ = d;
  114. if (d < min_delay_)
  115. min_delay_ = d;
  116. delay_sum_ += d;
  117. if (i == maxpkt_ + 1)
  118. {
  119. maxpkt_++;
  120. if (++gap_->start_ > gap_->end_)
  121. {
  122. g = gap_;
  123. gap_ = gap_->next_;
  124. if (gap_)
  125. maxpkt_ = gap_->start_ - 1;
  126. else {
  127. maxpkt_ = nextpkt_ - 1;
  128. tail_ = 0;
  129. }
  130. delete g;
  131. }
  132. return;
  133. }
  134. g = gap_;
  135. }
  136. else {
  137. double d;
  138. // locate gap this packet belongs to
  139. pg = gap_;
  140. g = gap_->next_;
  141. while (!(i >= g->start_ && i <= g->end_))
  142. {
  143. pg = g;
  144. g = g->next_;
  145. }
  146. d = tnow - g->time_;
  147. delay_sum_ += d;
  148. if (d > max_delay_) max_delay_ = d;
  149. if (d < min_delay_) min_delay_ = d;
  150. // first packet in gap
  151. if (g->start_ == i)
  152. {
  153. if (++g->start_ > g->end_)
  154. {
  155. pg->next_ = g->next_;
  156. if (tail_ == g)
  157. tail_ = pg;
  158. delete g;
  159. }
  160. return;
  161. }
  162. }
  163. // last packet in gap
  164. if (g->end_ == i)
  165. {
  166. g->end_--;
  167. return;
  168. }
  169. // a packet in the middle of gap
  170. pg = new Gap;
  171. pg->start_ = i+1;
  172. pg->end_   = g->end_;
  173. pg->time_  = g->time_;
  174. pg->next_  = g->next_;
  175. g->next_ = pg;
  176. g->end_  = i-1;
  177. if (tail_ == g)
  178. tail_ = pg;
  179. }
  180. //
  181. // Return 0 if packet does not exist in the
  182. // buffer, 1 if it does
  183. //
  184. int RcvBuffer::exists_pkt (int i)
  185. {
  186. if (i <= maxpkt_)  return 1;
  187. if (i >= nextpkt_) return 0;
  188. Gap *g;
  189. for (g = gap_; g; g = g->next_)
  190. if (g->start_ <= i && i <= g->end_)
  191. return 0;
  192. return 1;
  193. }
  194. void RcvBuffer::print ()
  195. {
  196. Gap *g;
  197. printf ("maxpkt: %d ", maxpkt_);
  198. for (g = gap_; g; g = g->next_)
  199. printf ("(%d, %d) ", g->start_, g->end_);
  200. printf ("nextpkt: %dn", nextpkt_);
  201. }