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

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /*
  3.  * empftp.cc
  4.  * Copyright (C) 2001 by the University of Southern California
  5.  * $Id: empftp.cc,v 1.5 2005/08/25 18:58:05 johnh Exp $
  6.  *
  7.  * This program is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU General Public License,
  9.  * version 2, as published by the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License along
  17.  * with this program; if not, write to the Free Software Foundation, Inc.,
  18.  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  19.  *
  20.  *
  21.  * The copyright of this module includes the following
  22.  * linking-with-specific-other-licenses addition:
  23.  *
  24.  * In addition, as a special exception, the copyright holders of
  25.  * this module give you permission to combine (via static or
  26.  * dynamic linking) this module with free software programs or
  27.  * libraries that are released under the GNU LGPL and with code
  28.  * included in the standard release of ns-2 under the Apache 2.0
  29.  * license or under otherwise-compatible licenses with advertising
  30.  * requirements (or modified versions of such code, with unchanged
  31.  * license).  You may copy and distribute such a system following the
  32.  * terms of the GNU GPL for this module and the licenses of the
  33.  * other code concerned, provided that you include the source code of
  34.  * that other code when and as the GNU GPL requires distribution of
  35.  * source code.
  36.  *
  37.  * Note that people who make modified versions of this module
  38.  * are not obligated to grant this special exception for their
  39.  * modified versions; it is their choice whether to do so.  The GNU
  40.  * General Public License gives permission to release a modified
  41.  * version without this exception; this exception also makes it
  42.  * possible to release a modified version which carries forward this
  43.  * exception.
  44.  *
  45.  */
  46. //
  47. // Empirical FTP traffic model that simulates FTP traffic based on a set of
  48. // CDF (Cumulative Distribution Function) data derived from live tcpdump trace
  49. // The structure of this file is largely borrowed from empweb.cc
  50. //
  51. #include <tclcl.h>
  52. #include "empftp.h"
  53. int EmpFtpTrafSession::LASTFILE_ = 1;
  54. // XXX Must delete this after all pages are done!!
  55. EmpFtpTrafSession::~EmpFtpTrafSession() 
  56. {
  57. if (nFile_ != curFile_) {
  58. fprintf(stderr, "done files %d != all files %dn",
  59. nFile_, curFile_);
  60. abort();
  61. }
  62. if (status_ != TIMER_IDLE) {
  63. fprintf(stderr, "EmpFtpTrafSession must be idle when deleted.n");
  64. abort();
  65. }
  66. /*
  67. if (rvInterPage_ != NULL)
  68. Tcl::instance().evalf("delete %s", rvInterPage_->name());
  69. if (rvPageSize_ != NULL)
  70. Tcl::instance().evalf("delete %s", rvPageSize_->name());
  71. if (rvInterObj_ != NULL)
  72. Tcl::instance().evalf("delete %s", rvInterObj_->name());
  73. if (rvObjSize_ != NULL)
  74. Tcl::instance().evalf("delete %s", rvObjSize_->name());
  75. if (rvReqSize_ != NULL)
  76. Tcl::instance().evalf("delete %s", rvReqSize_->name());
  77. if (rvPersistSel_ != NULL)
  78. Tcl::instance().evalf("delete %s", rvPersistSel_->name());
  79. if (rvServerSel_ != NULL)
  80. Tcl::instance().evalf("delete %s", rvServerSel_->name());
  81. */
  82. }
  83. // Launch the current file
  84. void EmpFtpTrafSession::expire(Event *)
  85. {
  86. if (curFile_ >= nFile_) return;
  87. sendFile(LASTFILE_++, (int)ceil(rvFileSize_->value()));
  88. if (mgr_->isdebug())
  89. printf("Session %d starting file %d, curfile %d n", 
  90.        id_, LASTFILE_-1, curFile_);
  91. }
  92. void EmpFtpTrafSession::handle(Event *e)
  93. {
  94.         TimerHandler::handle(e);
  95.      if (curFile_ < nFile_) {
  96.              // If this is not the last file, schedule the next
  97.                 // one. Otherwise stop and tell session to delete itself.
  98.                 curFile_++;
  99. sched(rvInterFile_->value());
  100.       } else
  101.      mgr_->doneSession(id_);
  102. }
  103. // Launch a request for a particular object
  104. void EmpFtpTrafSession::sendFile(int file, int size)
  105. {
  106. int wins = int(ceil(serverWin()->value()));
  107. int winc = int(ceil(clientWin()->value()));
  108. int window = (wins >= winc) ? wins : winc;
  109. // Choose source and dest TCP agents for both source and destination
  110. // TcpAgent* ctcp = mgr_->picktcp(window);
  111. TcpAgent* stcp = mgr_->picktcp(window);
  112. // TcpSink* csnk = mgr_->picksink();
  113. TcpSink* ssnk = mgr_->picksink();
  114. // Setup new TCP connection and launch request
  115. Tcl::instance().evalf("%s send-file %d %s %s %s %s %d %d", 
  116.       mgr_->name(), file, src_->name(), 
  117.        dst_->name(), stcp->name(), ssnk->name(), size, mgr_->color_);
  118. // Debug only
  119. // $numPacket_ $objectId_ $pageId_ $sessionId_ [$ns_ now] src dst
  120. if (mgr_->isdebug()) {
  121. printf("%d t %d t %d t %g %d %dn", size, file, id_,
  122.        Scheduler::instance().clock(), 
  123.        src_->address(), dst_->address());
  124. printf("** Tcp agents %d, Tcp sinks %dn", mgr_->nTcp(),mgr_->nSink());
  125. }
  126. }
  127. static class EmpFtpTrafPoolClass : public TclClass {
  128. public:
  129.         EmpFtpTrafPoolClass() : TclClass("PagePool/EmpFtpTraf") {}
  130.         TclObject* create(int, const char*const*) {
  131. return (new EmpFtpTrafPool());
  132. }
  133. } class_empwebtrafpool;
  134. EmpFtpTrafPool::~EmpFtpTrafPool()
  135. {
  136. if (session_ != NULL) {
  137. for (int i = 0; i < nSession_; i++)
  138. delete session_[i];
  139. delete []session_;
  140. }
  141. if (server_ != NULL)
  142. delete []server_;
  143. if (client_ != NULL)
  144. delete []client_;
  145. // XXX Destroy tcpPool_ and sinkPool_ ?
  146. }
  147. void EmpFtpTrafPool::delay_bind_init_all()
  148. {
  149. delay_bind_init_one("debug_");
  150. PagePool::delay_bind_init_all();
  151. }
  152. int EmpFtpTrafPool::delay_bind_dispatch(const char *varName,const char *localName,
  153.      TclObject *tracer)
  154. {
  155. if (delay_bind_bool(varName, localName, "debug_", &debug_, tracer)) 
  156. return TCL_OK;
  157. return PagePool::delay_bind_dispatch(varName, localName, tracer);
  158. }
  159. EmpFtpTrafPool::EmpFtpTrafPool() : 
  160. nSrc_(0), server_(NULL), session_(NULL), nClient_(0), client_(NULL),
  161. nTcp_(0), nSink_(0)
  162. {
  163. LIST_INIT(&tcpPool_);
  164. LIST_INIT(&sinkPool_);
  165. }
  166. TcpAgent* EmpFtpTrafPool::picktcp(int win)
  167. {
  168. TcpAgent* a = (TcpAgent*)detachHead(&tcpPool_);
  169. if (a == NULL) {
  170. Tcl& tcl = Tcl::instance();
  171. tcl.evalf("%s alloc-tcp %d", name(), win);
  172. a = (TcpAgent*)lookup_obj(tcl.result());
  173. if (a == NULL) {
  174. fprintf(stderr, "Failed to allocate a TCP agentn");
  175. abort();
  176. }
  177. } else 
  178. nTcp_--;
  179. return a;
  180. }
  181. TcpSink* EmpFtpTrafPool::picksink()
  182. {
  183. TcpSink* a = (TcpSink*)detachHead(&sinkPool_);
  184. if (a == NULL) {
  185. Tcl& tcl = Tcl::instance();
  186. tcl.evalf("%s alloc-tcp-sink", name());
  187. a = (TcpSink*)lookup_obj(tcl.result());
  188. if (a == NULL) {
  189. fprintf(stderr, "Failed to allocate a TCP sinkn");
  190. abort();
  191. }
  192. } else 
  193. nSink_--;
  194. return a;
  195. }
  196. int EmpFtpTrafPool::command(int argc, const char*const* argv)
  197. {
  198. if (argc == 3) {
  199. if (strcmp(argv[1], "set-num-session") == 0) {
  200. if (session_ != NULL) {
  201. for (int i = 0; i < nSession_; i++) 
  202. delete session_[i];
  203. delete []session_;
  204. }
  205. nSession_ = atoi(argv[2]);
  206. session_ = new EmpFtpTrafSession*[nSession_];
  207. memset(session_, 0, sizeof(EmpFtpTrafSession*)*nSession_);
  208. return (TCL_OK);
  209. } else if (strcmp(argv[1], "set-num-server-lan") == 0) {
  210. nSrcL_ = atoi(argv[2]);
  211. if (nSrcL_ >  nSrc_) {
  212. fprintf(stderr, "Wrong server index %dn", nSrcL_);
  213. return TCL_ERROR;
  214. }
  215. return (TCL_OK);
  216. } else if (strcmp(argv[1], "set-num-remote-client") == 0) {
  217. nClientL_ = atoi(argv[2]);
  218. if (nClientL_ > nClient_) {
  219. fprintf(stderr, "Wrong client index %dn", nClientL_);
  220. return TCL_ERROR;
  221. }
  222. return (TCL_OK);
  223. } else if (strcmp(argv[1], "set-num-server") == 0) {
  224. nSrc_ = atoi(argv[2]);
  225. if (server_ != NULL) 
  226. delete []server_;
  227. server_ = new Node*[nSrc_];
  228. return (TCL_OK);
  229. } else if (strcmp(argv[1], "set-num-client") == 0) {
  230. nClient_ = atoi(argv[2]);
  231. if (client_ != NULL) 
  232. delete []client_;
  233. client_ = new Node*[nClient_];
  234. return (TCL_OK);
  235. }
  236. } else if (argc == 4) {
  237. if (strcmp(argv[1], "set-server") == 0) {
  238. Node* cli = (Node*)lookup_obj(argv[3]);
  239. if (cli == NULL)
  240. return (TCL_ERROR);
  241. int nc = atoi(argv[2]);
  242. if (nc >= nSrc_) {
  243. fprintf(stderr, "Wrong server index %dn", nc);
  244. return TCL_ERROR;
  245. }
  246. server_[nc] = cli;
  247. return (TCL_OK);
  248. } else if (strcmp(argv[1], "set-client") == 0) {
  249. Node* s = (Node*)lookup_obj(argv[3]);
  250. if (s == NULL)
  251. return (TCL_ERROR);
  252. int n = atoi(argv[2]);
  253. if (n >= nClient_) {
  254. fprintf(stderr, "Wrong client index %dn", n);
  255. return TCL_ERROR;
  256. }
  257. client_[n] = s;
  258. return (TCL_OK);
  259. } else if (strcmp(argv[1], "recycle") == 0) {
  260. // <obj> recycle <tcp> <sink>
  261. //
  262. // Recycle a TCP source/sink pair
  263. Agent* tcp = (Agent*)lookup_obj(argv[2]);
  264. Agent* snk = (Agent*)lookup_obj(argv[3]);
  265. nTcp_++, nSink_++;
  266. if ((tcp == NULL) || (snk == NULL))
  267. return (TCL_ERROR);
  268. // XXX TBA: recycle tcp agents
  269. insertAgent(&tcpPool_, tcp);
  270. insertAgent(&sinkPool_, snk);
  271. return (TCL_OK);
  272. }
  273. } else if (argc == 12) {
  274. if (strcmp(argv[1], "create-session") == 0) {
  275. // <obj> create-session <session_index>
  276. //   <files_per_sess> <launch_time>
  277. //   <inter_file_rv> <file_size_rv>
  278. //   <server_sel_rv>
  279. //   <inbound/outbound flag>
  280. int n = atoi(argv[2]);
  281. if ((n < 0)||(n >= nSession_)||(session_[n] != NULL)) {
  282. fprintf(stderr,"Invalid session index %dn",n);
  283. return (TCL_ERROR);
  284. }
  285. int nfile = (int)strtod(argv[3], NULL);
  286. double lt = strtod(argv[4], NULL);
  287. int flip = atoi(argv[10]);
  288. if ((flip < 0)||(flip > 1)) {
  289. fprintf(stderr,"Invalid I/O flag %dn",flip);
  290. return (TCL_ERROR);
  291. }
  292. color_ = atoi(argv[11]);
  293. EmpFtpTrafSession* p = 
  294. new EmpFtpTrafSession(this, nfile, n);
  295. int res = lookup_rv(p->interFile(), argv[5]);
  296. res = (res == TCL_OK) ? 
  297. lookup_rv(p->fileSize(), argv[6]) : TCL_ERROR;
  298.     res = (res == TCL_OK) ?
  299.            lookup_rv(p->serverSel(), argv[7]) : TCL_ERROR;
  300.     res = (res == TCL_OK) ?
  301.            lookup_rv(p->serverWin(), argv[8]) : TCL_ERROR;
  302.     res = (res == TCL_OK) ?
  303.            lookup_rv(p->clientWin(), argv[9]) : TCL_ERROR;
  304. if (res == TCL_ERROR) {
  305. delete p;
  306. fprintf(stderr, "Invalid random variablen");
  307. return (TCL_ERROR);
  308. }
  309.                         int cl, svr;
  310. if (flip == 1) {
  311.                            cl = int(floor(Random::uniform(0, nClientL_)));
  312. svr=0;
  313. } else {
  314.                            cl = int(floor(Random::uniform(nClientL_, nClient_)));
  315.             svr= int(ceil(p->serverSel()->value()));
  316. }
  317.                         assert((cl >= 0) && (cl < nClient_));
  318. printf("%d %dn",svr , nSrc_);
  319.          assert((svr >= 0) && (svr < nSrc_));
  320.                         Node* c=client_[cl];
  321.          Node* s=server_[svr];
  322. p->setClient(c);
  323. p->setServer(s);
  324. p->sched(lt);
  325. session_[n] = p;
  326.        
  327. return (TCL_OK);
  328. }
  329. }
  330. return PagePool::command(argc, argv);
  331. }