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

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /*
  3.  * Copyright (c) Xerox Corporation 1997. All rights reserved.
  4.  *  
  5.  * This program is free software; you can redistribute it and/or modify it
  6.  * under the terms of the GNU General Public License as published by the
  7.  * Free Software Foundation; either version 2 of the License, or (at your
  8.  * option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful, but
  11.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * 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.  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  18.  *
  19.  * Linking this file statically or dynamically with other modules is making
  20.  * a combined work based on this file.  Thus, the terms and conditions of
  21.  * the GNU General Public License cover the whole combination.
  22.  *
  23.  * In addition, as a special exception, the copyright holders of this file
  24.  * give you permission to combine this file with free software programs or
  25.  * libraries that are released under the GNU LGPL and with code included in
  26.  * the standard release of ns-2 under the Apache 2.0 license or under
  27.  * otherwise-compatible licenses with advertising requirements (or modified
  28.  * versions of such code, with unchanged license).  You may copy and
  29.  * distribute such a system following the terms of the GNU GPL for this
  30.  * file and the licenses of the other code concerned, provided that you
  31.  * include the source code of that other code when and as the GNU GPL
  32.  * requires distribution of source code.
  33.  *
  34.  * Note that people who make modified versions of this file are not
  35.  * obligated to grant this special exception for their modified versions;
  36.  * it is their choice whether to do so.  The GNU General Public License
  37.  * gives permission to release a modified version without this exception;
  38.  * this exception also makes it possible to release a modified version
  39.  * which carries forward this exception.
  40.  */
  41. #ifndef lint
  42. static const char rcsid[] =
  43.     "@(#) $Header: /cvsroot/nsnam/ns-2/trace/traffictrace.cc,v 1.16 2005/08/26 05:05:31 tomh Exp $ (Xerox)";
  44. #endif
  45. /* XXX: have not dealt with errors.  e.g., if something fails during
  46.  * TraceFile::setup(), or TrafficTrace is not pointing to a TraceFile,
  47.  * no guarantee about results.
  48.  */
  49.  
  50. #include <sys/types.h>
  51. #include <sys/stat.h> 
  52. #include <stdio.h>
  53. #include "config.h"
  54. #ifdef HAVE_NETINET_IN_H
  55. #include <netinet/in.h>
  56. #endif /* HAVE_NETINET_IN_H */
  57. #include "random.h"
  58. /* module to implement a traffic generator in ns driven by a trace
  59.  * file.  records in the trace file consist of 2 32 bit fields, the
  60.  * first indicating the inter-packet time in microseconds, and the
  61.  * second indicating the packet length in bytes.  multiple TraffficTrace
  62.  * objects can use the same trace file, and different TrafficTrace
  63.  * objects can use different trace files.  For each TrafficTrace, a
  64.  * random starting point within the trace file is selected.
  65.  */
  66. #include "object.h"
  67. #include "trafgen.h"
  68. struct tracerec {
  69.         u_int32_t trec_time; /* inter-packet time (usec) */
  70. u_int32_t trec_size; /* size of packet (bytes */
  71. };
  72. /* object to hold a single trace file */
  73. class TraceFile : public NsObject {
  74.  public:
  75. TraceFile();
  76. void get_next(int&, struct tracerec&); /* called by TrafficGenerator
  77. * to get next record in trace.
  78. */
  79. int setup();  /* initialize the trace file */
  80. int command(int argc, const char*const* argv);
  81.  private:
  82. void recv(Packet*, Handler*); /* must be defined for NsObject */
  83.         int status_; 
  84. char *name_;  /* name of the file in which the trace is stored */
  85. int nrec_;    /* number of records in the trace file */
  86. struct tracerec *trace_; /* array holding the trace */
  87. };
  88. /* instance of a traffic generator.  has a pointer to the TraceFile
  89.  * object and implements the interval() function.
  90.  */
  91. class TrafficTrace : public TrafficGenerator {
  92.  public:
  93. TrafficTrace();
  94. int command(int argc, const char*const* argv);
  95. virtual double next_interval(int &);
  96.  protected:
  97. void timeout();
  98. TraceFile *tfile_;
  99. struct tracerec trec_;
  100. int ndx_;
  101. void init();
  102. };
  103. static class TraceFileClass : public TclClass {
  104.  public:
  105. TraceFileClass() : TclClass("Tracefile") {}
  106. TclObject* create(int, const char*const*) {
  107. return (new TraceFile());
  108. }
  109. } class_tracefile;
  110. TraceFile::TraceFile() : status_(0)
  111. {
  112. }
  113. int TraceFile::command(int argc, const char*const* argv)
  114. {
  115. if (argc == 3) {
  116. if (strcmp(argv[1], "filename") == 0) {
  117. name_ = new char[strlen(argv[2])+1];
  118. strcpy(name_, argv[2]);
  119. return(TCL_OK);
  120. }
  121. }
  122. return (NsObject::command(argc, argv));
  123. }
  124. void TraceFile::get_next(int& ndx, struct tracerec& t)
  125. {
  126. t.trec_time = trace_[ndx].trec_time;
  127. t.trec_size = trace_[ndx].trec_size;
  128. if (++ndx == nrec_)
  129. ndx = 0;
  130. }
  131. int TraceFile::setup()
  132. {
  133. tracerec* t;
  134. struct stat buf;
  135. int i;
  136. FILE *fp;
  137. /* only open/read the file once (could be shared by multiple
  138.  * SourceModel's
  139.  */
  140. if (! status_) {
  141. status_ = 1;
  142. if (stat(name_, (struct stat *)&buf)) {
  143. printf("could not stat %sn", name_);
  144. return -1;
  145. }
  146. nrec_ = buf.st_size/sizeof(tracerec);
  147. unsigned nrecplus = nrec_ * sizeof(tracerec);
  148. unsigned bufst = buf.st_size;
  149. // if ((unsigned)(nrec_ * sizeof(tracerec)) != buf.st_size) {
  150. if (nrecplus != bufst) {
  151. printf("bad file size in %sn", name_);
  152. return -1;
  153. }
  154. trace_ = new struct tracerec[nrec_];
  155. if ((fp = fopen(name_, "rb")) == NULL) {
  156. printf("can't open file %sn", name_);
  157. return -1;
  158. }
  159. for (i = 0, t = trace_; i < nrec_; i++, t++)
  160. if (fread((char *)t, sizeof(tracerec), 1, fp) != 1) {
  161. printf("read failedn");
  162. return -1 ;
  163. }
  164. else {
  165. t->trec_time = ntohl(t->trec_time);
  166. t->trec_size = ntohl(t->trec_size);
  167. }
  168. }
  169. /* pick a random starting place in the trace file */
  170. return (int(Random::uniform((double)nrec_)+.5));
  171. }
  172. void TraceFile::recv(Packet*, Handler*)
  173. {
  174.         /* shouldn't get here */
  175.         abort();
  176. }
  177. /**************************************************************/
  178. static class TrafficTraceClass : public TclClass {
  179.  public:
  180. TrafficTraceClass() : TclClass("Application/Traffic/Trace") {}
  181. TclObject* create(int, const char*const*) {
  182.         return(new TrafficTrace());
  183. }
  184. } class_traffictrace;
  185. TrafficTrace::TrafficTrace()
  186. {
  187. tfile_ = (TraceFile *)NULL;
  188. }
  189. void TrafficTrace::init()
  190. {
  191. if (tfile_) 
  192. ndx_ = tfile_->setup();
  193. }
  194. int TrafficTrace::command(int argc, const char*const* argv)
  195. {
  196. Tcl& tcl = Tcl::instance();
  197. if (argc == 3) {
  198. if (strcmp(argv[1], "attach-tracefile") == 0) {
  199. tfile_ = (TraceFile *)TclObject::lookup(argv[2]);
  200. if (tfile_ == 0) {
  201. tcl.resultf("no such node %s", argv[2]);
  202. return(TCL_ERROR);
  203. }
  204. return(TCL_OK);
  205. }
  206. }
  207. return (TrafficGenerator::command(argc, argv));
  208. }
  209. void TrafficTrace::timeout()
  210. {
  211.         if (! running_)
  212.                 return;
  213.         /* send a packet */
  214. // Note:  May need to set "NEW_BURST" flag in sendmsg() for 
  215. // signifying a new talkspurt when using vat traces.
  216. // (see expoo.cc, tcl/ex/test-rcvr.tcl)
  217. agent_->sendmsg(size_);
  218.         /* figure out when to send the next one */
  219.         nextPkttime_ = next_interval(size_);
  220.         /* schedule it */
  221.         timer_.resched(nextPkttime_);
  222. }
  223. double TrafficTrace::next_interval(int& size)
  224. {
  225.         tfile_->get_next(ndx_, trec_);
  226. size = trec_.trec_size;
  227. return(((double)trec_.trec_time)/1000000.0); /* usecs->secs */
  228. }