1.1 --- a/examples/tcp-2way.cc Sat Aug 09 10:52:36 2008 -0700
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,785 +0,0 @@
1.4 -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
1.5 -/*
1.6 - * Copyright 2007 University of Washington
1.7 - * Copyright 2007 Georgia Tech Research Corporation
1.8 - * Copyright 2008 Sandia Corporation
1.9 - *
1.10 - * This program is free software; you can redistribute it and/or modify
1.11 - * it under the terms of the GNU General Public License version 2 as
1.12 - * published by the Free Software Foundation;
1.13 - *
1.14 - * This program is distributed in the hope that it will be useful,
1.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.17 - * GNU General Public License for more details.
1.18 - *
1.19 - * You should have received a copy of the GNU General Public License
1.20 - * along with this program; if not, write to the Free Software
1.21 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1.22 - *
1.23 - *
1.24 - * Sandia is a multiprogram laboratory operated by Sandia
1.25 - * Corporation, a Lockheed Martin Company, for the United States
1.26 - * Department of Energy's National Nuclear Security Administration
1.27 - * under Contract DE-AC04-94AL85000.
1.28 - *
1.29 - * Author: David Evensky, Sandia National Labs
1.30 - *
1.31 - * includes GPL'ed ns-3-dev code from:
1.32 - * udp-echo, // ??, (c) U. Wash. 2007
1.33 - * tcp-large-transfer // ??
1.34 - * packet-sink // Tom Henderson, (c) U. Wash. 2007
1.35 - * onoff // George F. Riley, (c) GT Res Corp. 2007
1.36 - */
1.37 -
1.38 -
1.39 -/* NOTE
1.40 -This isn't really an example file, so don't look to closely at it as a starting
1.41 -script. It is here for validation of the TCP model.
1.42 -*/
1.43 -
1.44 -#include <iostream>
1.45 -#include <fstream>
1.46 -#include <sstream>
1.47 -#include <string>
1.48 -#include <iomanip>
1.49 -#include <map>
1.50 -
1.51 -#include "ns3/core-module.h"
1.52 -#include "ns3/helper-module.h"
1.53 -#include "ns3/node-module.h"
1.54 -#include "ns3/global-route-manager.h"
1.55 -#include "ns3/simulator-module.h"
1.56 -#include "ns3/log.h"
1.57 -
1.58 -using namespace ns3;
1.59 -
1.60 -NS_LOG_COMPONENT_DEFINE ("tcp-2way");
1.61 -
1.62 -//----------defines-------------------------------------------------------------
1.63 -//define to print more debugging info.
1.64 -#define VERBOSE_TESTING
1.65 -
1.66 -/* define to die because Socket::Recv() is told to
1.67 - * only read an "undesired" number of bytes
1.68 - * fails NS_ASSERT in HandleRead because rx_addr_tag
1.69 - * tag isn't there.
1.70 - */
1.71 -//#define TOO_SMALL_BUG
1.72 -
1.73 -//define to print this pointer in NS_LOG_FUNCTION
1.74 -//#define PRINT_THIS
1.75 -
1.76 -/*define to print packet info in HandleRead
1.77 - *expected output is of the form:
1.78 - *536:P{536} *bytes from 10.1.0.2 [02-06-0a:01:00:02:20:00] <0|536|884018>
1.79 - * ^ ^ ^ ^ ^ ^ ^ ^
1.80 - * | | | | | | | |
1.81 - * | | | | | | | +bytes left
1.82 - * | | | | | | | to read in
1.83 - * | | | | | | | sent buffer
1.84 - * | | | | | | +bytes read in
1.85 - * | | | | | | this packet if
1.86 - * | | | | | | header read,
1.87 - * | | | | | | prints size
1.88 - * | | | | | | in ()
1.89 - * | | | | | +bytes cur. packet
1.90 - * | | | | | left to process
1.91 - * | | | | +mac addr of sender
1.92 - * | | | +IP addr of sender
1.93 - * | | +print '*' while processing first chunk in a received packet.
1.94 - * | | if there are multiple small sent packets, these can appear in
1.95 - * | | a single packet, and are processed by a do {} while() loop.
1.96 - * | +rle output of packet::PeekData(), in this case filled with 536 bytes
1.97 - * | filled with the letter 'P' (brought to you by the letter 'Q' and the
1.98 - * | number '9' :-))
1.99 - * + packet::GetSize()
1.100 - *
1.101 - * If there is a header it will look more like:
1.102 - * 536:N{317}@B.{6}HELLOP{206} *bytes from 10.1.0.2 [02-06-0a:01:00:02:20:00]\
1.103 - * <219|317|0>
1.104 - * 536:N{317}@B.{6}HELLOP{206} bytes from 10.1.0.2 [02-06-0a:01:00:02:20:00]\
1.105 - * <0|206(13)|999794> (ArchHeader=HELLO:1000000)
1.106 - * where you can see that this first packet includes 317 bytes from the
1.107 - * previous send packet (filled with N) and 13 bytes of header before the 206
1.108 - * bytes of payload (filled with P).
1.109 - */
1.110 -
1.111 -#define RECV_PRINT
1.112 -
1.113 -// dcl non-method functions....
1.114 -std::string rle(const uint8_t *, int );
1.115 -std::ofstream fileOut("tcp-2way.out");
1.116 -
1.117 -//----------class ArchHeader dcl and definition---------------------------------
1.118 -/*
1.119 - * ArchHeader: A toy header that holds a string
1.120 - * and a uint32_t. The string is an abitrary label
1.121 - * and the int is used as the length of the payload.
1.122 - */
1.123 -
1.124 -class ArchHeader : public Header {
1.125 -public:
1.126 - virtual uint32_t GetSerializedSize (void) const;
1.127 - virtual void Serialize (Buffer::Iterator) const;
1.128 - virtual uint32_t Deserialize (Buffer::Iterator);
1.129 - virtual void Print (std::ostream &) const;
1.130 - static TypeId GetTypeId (void);
1.131 - virtual TypeId GetInstanceTypeId (void) const;
1.132 -
1.133 - // accessor functions.....
1.134 - void SetIntValue (uint32_t);
1.135 - uint32_t GetIntValue (void) const;
1.136 - void SetStrValue (const std::string &s);
1.137 - std::string GetStrValue (void) const;
1.138 -private:
1.139 - uint32_t int_value;
1.140 - std::string str_value;
1.141 -};
1.142 -
1.143 -
1.144 -TypeId
1.145 -ArchHeader::GetTypeId (void)
1.146 -{
1.147 - static TypeId tid = TypeId ("ns3::ArchHeader")
1.148 - .AddConstructor<ArchHeader> () // NOTE: Required for ????
1.149 - .SetParent<Header> () // ditto
1.150 - ;
1.151 - return tid;
1.152 -}
1.153 -
1.154 -TypeId
1.155 -ArchHeader::GetInstanceTypeId (void) const
1.156 -{
1.157 - return GetTypeId ();
1.158 -}
1.159 -
1.160 -uint32_t
1.161 -ArchHeader::GetSerializedSize (void) const
1.162 -{
1.163 - return 2*sizeof (uint32_t) + str_value.size (); // int, str len & bytes
1.164 -}
1.165 -
1.166 -void
1.167 -ArchHeader::Serialize (Buffer::Iterator i) const
1.168 -{
1.169 - i.WriteU32 (int_value);
1.170 - uint32_t str_len = str_value.size ();
1.171 - i.WriteU32 (str_len);
1.172 - for (uint32_t j = 0; j < str_value.size (); j++)
1.173 - i.WriteU8 (str_value[j]);
1.174 -}
1.175 -
1.176 -uint32_t
1.177 -ArchHeader::Deserialize (Buffer::Iterator i)
1.178 -{
1.179 - int_value = i.ReadU32 ();
1.180 - uint32_t str_len = i.ReadU32 ();
1.181 - str_value.reserve (str_len);
1.182 - for (uint32_t j = 0; j < str_len; j++) {
1.183 - char v = i.ReadU8 ();
1.184 - str_value.push_back (v);
1.185 - }
1.186 - return 2*sizeof (uint32_t) + str_value.size ();
1.187 -}
1.188 -
1.189 -
1.190 -void
1.191 -ArchHeader::SetIntValue (uint32_t v_)
1.192 -{
1.193 - int_value = v_;
1.194 -}
1.195 -
1.196 -uint32_t
1.197 -ArchHeader::GetIntValue (void) const
1.198 -{
1.199 - return int_value;
1.200 -}
1.201 -
1.202 -void
1.203 -ArchHeader::SetStrValue (const std::string &s)
1.204 -{
1.205 - str_value = s;
1.206 -}
1.207 -
1.208 -std::string
1.209 -ArchHeader::GetStrValue (void) const
1.210 -{
1.211 - return str_value;
1.212 -}
1.213 -
1.214 -void
1.215 -ArchHeader::Print (std::ostream &os) const
1.216 -{
1.217 - os << "(ArchHeader=" << str_value << ":" << int_value << ")";
1.218 -}
1.219 -
1.220 -//----------class TalkerApp dcl and definition----------------------------------
1.221 -/*
1.222 - * TalkerApp:
1.223 - * An an Application that can serve as both Rx and Tx side.
1.224 - * and is configured by ConfRecv/ConfSend and driven by
1.225 - * ScheduleSendPacket. Becareful not to try to send a packet
1.226 - * from the Rx side to the Tx side (back channel) before the
1.227 - * connection is setup, which has to be from the Tx to the Rx
1.228 - * (the forward channel).
1.229 - */
1.230 -
1.231 -class TalkerApp : public Application {
1.232 -public:
1.233 - TalkerApp ();
1.234 - virtual ~TalkerApp ();
1.235 - void ConfRecv (Ptr<Node>,const Address &);
1.236 - void ConfSend (Ptr<Node>,const Address &);
1.237 - void ScheduleSendPacket(const Time ,const char , const uint32_t size );
1.238 -
1.239 -protected:
1.240 - virtual void DoDispose (void);
1.241 -private:
1.242 - virtual void StartApplication (void);
1.243 - virtual void StopApplication (void);
1.244 -
1.245 - void StartApplicationRecv (void);
1.246 - void StartApplicationSend (void);
1.247 -
1.248 - void HandleRead (Ptr<Socket>);
1.249 - void SendPacket (std::string,char,uint32_t);
1.250 -
1.251 - void CloseConnection (Ptr<Socket> socket);
1.252 - void ConnectionSucceeded (Ptr<Socket>);
1.253 - void ConnectionFailed (Ptr<Socket>);
1.254 - bool ConnectionRequested (Ptr<Socket>, const Address &);
1.255 - void ConnectionCreated (Ptr<Socket>, const Address &);
1.256 -
1.257 -
1.258 - bool verbose;
1.259 - Ptr<Socket> m_socket;
1.260 - Ptr<Socket> m_servsocket;
1.261 - Address m_local;
1.262 - Address m_remote;
1.263 - int i_am_listener;
1.264 - typedef std::map<Ptr<Socket>, uint32_t>::iterator left_to_read_iterator_type;
1.265 - std::map<Ptr<Socket>, uint32_t> m_left_to_read;
1.266 -};
1.267 -
1.268 -class TalkerApp_sub : public TalkerApp {
1.269 -public:
1.270 - int foo(void);
1.271 -};
1.272 -
1.273 -int
1.274 -TalkerApp_sub::foo(void) {return 0;}
1.275 -
1.276 -TalkerApp::TalkerApp () :
1.277 - verbose (false),
1.278 - m_socket (0),
1.279 - m_servsocket (0),
1.280 - i_am_listener (0)
1.281 -{}
1.282 -
1.283 -TalkerApp::~TalkerApp ()
1.284 -{}
1.285 -
1.286 -void
1.287 -TalkerApp::DoDispose (void)
1.288 -{
1.289 - m_socket = 0;
1.290 - m_servsocket = 0;
1.291 - Application::DoDispose ();
1.292 -}
1.293 -
1.294 -
1.295 -void
1.296 -TalkerApp::CloseConnection (Ptr<Socket> sock)
1.297 -{
1.298 - NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|")
1.299 -#ifdef PRINT_THIS
1.300 - << this
1.301 -#endif
1.302 - << sock
1.303 - );
1.304 - sock->Close ();
1.305 -}
1.306 -
1.307 -void
1.308 -TalkerApp::ConnectionSucceeded (Ptr<Socket> sock)
1.309 -{
1.310 - NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|")
1.311 -#ifdef PRINT_THIS
1.312 - << this
1.313 -#endif
1.314 - << sock
1.315 -
1.316 - );
1.317 -}
1.318 -
1.319 -void
1.320 -TalkerApp::ConnectionFailed (Ptr<Socket> sock)
1.321 -{
1.322 - NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|")
1.323 -#ifdef PRINT_THIS
1.324 - << this
1.325 -#endif
1.326 - << sock
1.327 - );
1.328 -}
1.329 -
1.330 -bool
1.331 -TalkerApp::ConnectionRequested (Ptr<Socket> sock, const Address &addr)
1.332 -{
1.333 - NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|")
1.334 -#ifdef PRINT_THIS
1.335 - << this
1.336 -#endif
1.337 - << sock
1.338 - << addr
1.339 - );
1.340 - return true;
1.341 -}
1.342 -
1.343 -void
1.344 -TalkerApp::ConnectionCreated (Ptr<Socket> sock, const Address &addr)
1.345 -{
1.346 - NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|")
1.347 -#ifdef PRINT_THIS
1.348 - << this
1.349 -#endif
1.350 - << sock
1.351 - << addr
1.352 - );
1.353 - m_socket = sock;
1.354 - m_socket->SetRecvCallback(MakeCallback (&TalkerApp::HandleRead, this));
1.355 -}
1.356 -
1.357 -void
1.358 -TalkerApp::ScheduleSendPacket (const Time dt,const char fill,
1.359 - const uint32_t size)
1.360 -{
1.361 - NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|")
1.362 -#ifdef PRINT_THIS
1.363 - << this
1.364 -#endif
1.365 - << dt
1.366 - << fill
1.367 - << size
1.368 - );
1.369 - Simulator::Schedule(dt,&TalkerApp::SendPacket, this,
1.370 - std::string("HELLO"),fill,size);
1.371 -}
1.372 -
1.373 -
1.374 -void
1.375 -TalkerApp::StartApplication ()
1.376 -{
1.377 - NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|")
1.378 -#ifdef PRINT_THIS
1.379 - << this
1.380 -#endif
1.381 - );
1.382 - if (i_am_listener)
1.383 - StartApplicationRecv ();
1.384 - else
1.385 - StartApplicationSend ();
1.386 -}
1.387 -
1.388 -void
1.389 -TalkerApp::StartApplicationSend ()
1.390 -{
1.391 - NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|")
1.392 -#ifdef PRINT_THIS
1.393 - << this
1.394 -#endif
1.395 - );
1.396 -
1.397 - if (!m_socket) {
1.398 - m_socket = Socket::CreateSocket (GetNode (),
1.399 - TcpSocketFactory::GetTypeId ());
1.400 - m_socket->Bind ();
1.401 - }
1.402 -
1.403 - m_socket->Connect (m_remote);
1.404 - m_socket->SetConnectCallback
1.405 - (
1.406 - MakeCallback (&TalkerApp::ConnectionSucceeded,this),
1.407 - MakeCallback (&TalkerApp::ConnectionFailed,this)
1.408 - );
1.409 - m_socket->SetRecvCallback (MakeCallback (&TalkerApp::HandleRead, this));
1.410 -}
1.411 -
1.412 -void
1.413 -TalkerApp::StartApplicationRecv ()
1.414 -{
1.415 - NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|")
1.416 -#ifdef PRINT_THIS
1.417 - << this
1.418 -#endif
1.419 - );
1.420 - if (!m_servsocket) {
1.421 - m_servsocket = Socket::CreateSocket (GetNode (),
1.422 - TcpSocketFactory::GetTypeId ());
1.423 - m_servsocket->Bind (m_local);
1.424 - m_servsocket->Listen (0);
1.425 - }
1.426 -
1.427 - m_servsocket->SetAcceptCallback
1.428 - (
1.429 - MakeCallback (&TalkerApp::ConnectionRequested,this),
1.430 - MakeCallback (&TalkerApp::ConnectionCreated,this)
1.431 - );
1.432 -}
1.433 -
1.434 -void
1.435 -TalkerApp::ConfRecv (Ptr<Node> node, const Address &addr)
1.436 -{
1.437 - i_am_listener = 1;
1.438 - NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|")
1.439 -#ifdef PRINT_THIS
1.440 - << this
1.441 -#endif
1.442 - << node
1.443 - << addr
1.444 - );
1.445 - m_local = addr;
1.446 - node->AddApplication (this);
1.447 -}
1.448 -
1.449 -void
1.450 -TalkerApp::ConfSend (Ptr<Node> node, const Address &addr)
1.451 -{
1.452 - i_am_listener = 0;
1.453 - NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|")
1.454 -#ifdef PRINT_THIS
1.455 - << this
1.456 -#endif
1.457 - << node
1.458 - << addr
1.459 - );
1.460 - m_remote = addr;
1.461 - node->AddApplication (this);
1.462 -}
1.463 -
1.464 -
1.465 -void
1.466 -TalkerApp::SendPacket (std::string label,char fill,uint32_t payloadsize)
1.467 -{
1.468 - NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|")
1.469 -#ifdef PRINT_THIS
1.470 - << this
1.471 -#endif
1.472 - << label
1.473 - << fill
1.474 - << payloadsize
1.475 - );
1.476 -
1.477 -#if 0
1.478 - Ptr<Packet> p = Create<Packet> (payloadsize); // zero byte filled packet.
1.479 -#else
1.480 - uint8_t *buf = (uint8_t *) malloc(payloadsize*sizeof(uint8_t));
1.481 - memset(buf,fill,payloadsize);
1.482 - Ptr<Packet> p = Create<Packet> (buf,payloadsize); // filled packet.
1.483 - free(buf);
1.484 -#endif
1.485 - if (verbose) {
1.486 - p->Print (fileOut << "Before Marking|");
1.487 - fileOut << std::endl;
1.488 - }
1.489 -
1.490 - ArchHeader hdr;
1.491 - hdr.SetStrValue (label);
1.492 - hdr.SetIntValue (p->GetSize());
1.493 - p->AddHeader (hdr);
1.494 - if (verbose) {
1.495 - p->Print(fileOut << "After Header Marking|");
1.496 - fileOut << std::endl;
1.497 - }
1.498 -
1.499 - m_socket->Send (p);
1.500 -}
1.501 -
1.502 -void
1.503 -TalkerApp::StopApplication ()
1.504 -{
1.505 - NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|")
1.506 -#ifdef PRINT_THIS
1.507 - << this
1.508 -#endif
1.509 - );
1.510 - if (m_socket)
1.511 - m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
1.512 -}
1.513 -
1.514 -void
1.515 -TalkerApp::HandleRead (Ptr<Socket> socket)
1.516 -{
1.517 - left_to_read_iterator_type iter = m_left_to_read.find (socket);
1.518 - if (iter == m_left_to_read.end ())
1.519 - m_left_to_read[socket] = 0;
1.520 -
1.521 - std::ostringstream pretty;
1.522 - pretty << (i_am_listener ? "Server" : "Client")
1.523 - << (iter == m_left_to_read.end () ?
1.524 - "(new)" : "(old)")
1.525 - << "|";
1.526 -
1.527 - NS_LOG_FUNCTION ( pretty.str ()
1.528 -#ifdef PRINT_THIS
1.529 - << this
1.530 -#endif
1.531 - << socket
1.532 - );
1.533 - /*
1.534 - * NOTE: I can crash with the # bytes == 500 rather than 536
1.535 - * which seems to be the default MTU
1.536 - */
1.537 -
1.538 -#ifdef TOO_SMALL_BUG
1.539 - const uint32_t number_of_bytes_willing_to_read = 500;
1.540 -#else
1.541 - const uint32_t number_of_bytes_willing_to_read = 536;
1.542 -#endif
1.543 - const uint32_t unused_flags = 0;
1.544 -
1.545 - Ptr<Packet> packet;
1.546 - while (packet = socket->Recv (number_of_bytes_willing_to_read,
1.547 - unused_flags) ){
1.548 - std::string raw_rle = rle(packet->PeekData(),
1.549 - packet->GetSize());
1.550 - SocketAddressTag rx_addr_tag;
1.551 - bool found;
1.552 - found = packet->FindFirstMatchingTag (rx_addr_tag);
1.553 - NS_ASSERT (found);
1.554 - Address from = rx_addr_tag.GetAddress ();
1.555 - // XXX packet->RemoveTag (tag);
1.556 - if (InetSocketAddress::IsMatchingType (from)) {
1.557 - InetSocketAddress address = InetSocketAddress::ConvertFrom (from);
1.558 -
1.559 -#ifdef VERBOSE_TESTING
1.560 - packet->Print (fileOut << "Packet Dump: ");
1.561 - fileOut << std::endl;
1.562 -#endif
1.563 -
1.564 -
1.565 - bool freshly_in_the_loop = true;
1.566 - do {
1.567 -#if defined(RECV_PRINT)
1.568 - fileOut
1.569 - << raw_rle // <length>:<rle of packet->PeekBuffer>
1.570 - << (freshly_in_the_loop ? " *" : " ") /* used to see if the do while
1.571 - * does anything */
1.572 - << "bytes from "
1.573 - << address.GetIpv4 () << " [" << address << "] ";
1.574 -#endif
1.575 - freshly_in_the_loop = false;
1.576 - int header_bytes = 0;
1.577 - ArchHeader* hdr = 0; // sadly, can't be a Ptr<>
1.578 - if (
1.579 - (m_left_to_read[socket] == 0)
1.580 - ) {
1.581 - hdr = new ArchHeader;
1.582 - if (packet->RemoveHeader (*hdr)) {
1.583 - m_left_to_read[socket] = hdr->GetIntValue ();
1.584 - header_bytes = hdr->GetSerializedSize ();
1.585 - } else {
1.586 - ; // never get here, ns3 dumps if no header is there.
1.587 - }
1.588 - }
1.589 - uint32_t num_bytes_processed = 0;
1.590 - if (m_left_to_read[socket] <= packet->GetSize ()) {
1.591 - packet->RemoveAtStart (m_left_to_read[socket]);
1.592 - num_bytes_processed = m_left_to_read[socket];
1.593 - m_left_to_read[socket] = 0;
1.594 -
1.595 - } else {
1.596 - m_left_to_read[socket] -= packet->GetSize ();
1.597 - num_bytes_processed = packet->GetSize ();
1.598 - packet->RemoveAtStart (packet->GetSize ());
1.599 - }
1.600 -
1.601 -#if defined(RECV_PRINT)
1.602 - fileOut
1.603 - << "<"
1.604 - << packet->GetSize ()
1.605 - << "|"
1.606 - << num_bytes_processed
1.607 - ;
1.608 - if (header_bytes)
1.609 - fileOut
1.610 - << "("
1.611 - << header_bytes
1.612 - << ")"
1.613 - ;
1.614 - fileOut
1.615 - << "|"
1.616 - << m_left_to_read[socket]
1.617 - << ">";
1.618 -#ifdef VERBOSE_TESTING
1.619 - if (hdr)
1.620 - hdr->Print(fileOut << " ");
1.621 -#endif
1.622 - fileOut << std::endl;
1.623 -#endif
1.624 - if (hdr)
1.625 - delete hdr; // free what we new....
1.626 - } while (
1.627 - packet->GetSize ()
1.628 - );
1.629 - } else {
1.630 - fileOut << "not a match in HandleRead" << std::endl;
1.631 - }
1.632 -
1.633 - }
1.634 -}
1.635 -
1.636 -//---------------Non-member functions-------------------------------------------
1.637 -/*
1.638 - * returns a string containing the length of the buffer,
1.639 - * followed by an run length encoded version of the buffer
1.640 - * un-printables are represented by '.' (i.e. special_marker
1.641 - * const).
1.642 - */
1.643 -std::string rle(const uint8_t *buf, int buflen) {
1.644 -
1.645 - int justify = 5;
1.646 - std::ostringstream o;
1.647 - const uint8_t min_rep = 3;
1.648 - uint8_t cur_char = 0;
1.649 - const uint8_t special_marker = '.';
1.650 - int cur_cnt = 0;
1.651 - if (justify) {
1.652 - o << std::setw(justify) << std::right << buflen << ":";
1.653 - } else {
1.654 - o << buflen << ":";
1.655 - }
1.656 -
1.657 - for (int i = 0; i < buflen; i++) {
1.658 - if (
1.659 - (!isprint(buf[i]) && cur_char == special_marker) ||
1.660 - (buf[i] == cur_char)
1.661 - )
1.662 - cur_cnt++;
1.663 - else {
1.664 - if (cur_cnt >= min_rep)
1.665 - o << (isprint(cur_char) ? static_cast<char>(cur_char) : '.') << "{"
1.666 - << cur_cnt << "}";
1.667 - else
1.668 - for (int irep=0; irep < cur_cnt; irep++)
1.669 - o << (isprint(cur_char) ? static_cast<char>(cur_char) : '.');
1.670 - if (isprint(buf[i]))
1.671 - cur_char = buf[i];
1.672 - else
1.673 - cur_char = special_marker;
1.674 - cur_cnt = 1;
1.675 - }
1.676 - }
1.677 - if (cur_cnt >= min_rep)
1.678 - o << (isprint(cur_char) ? static_cast<char>(cur_char) : '.') << "{"
1.679 - << cur_cnt << "}";
1.680 - else
1.681 - for (int irep=0; irep < cur_cnt; irep++)
1.682 - o << (isprint(cur_char) ? static_cast<char>(cur_char) : '.');
1.683 - return o.str();
1.684 -}
1.685 -
1.686 -//---------------Main-----------------------------------------------------------
1.687 -int
1.688 -main (int argc, char *argv[]) {
1.689 -
1.690 - std::clog.rdbuf (fileOut.rdbuf ()); /* till we can do this in ns3::log
1.691 - * without this ns3 logging messages
1.692 - * are far away from normal output
1.693 - */
1.694 -
1.695 -#ifdef VERBOSE_TESTING
1.696 - LogComponentEnable ("tcp-2way",LOG_LEVEL_ALL);
1.697 -#endif
1.698 -
1.699 - RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8);
1.700 - Packet::EnableMetadata ();
1.701 -
1.702 - // boilerplate: "c0[0]" is Tx, "c0[1]" is Rx.
1.703 - NodeContainer c0;
1.704 - c0.Create (2);
1.705 -
1.706 - // We create the channels first without any IP addressing information
1.707 - PointToPointHelper p2p;
1.708 - p2p.SetDeviceAttribute ("DataRate",DataRateValue (DataRate (10000000)));
1.709 - p2p.SetChannelAttribute ("Delay",TimeValue (MilliSeconds (10)));
1.710 - NetDeviceContainer dev0 = p2p.Install (c0);
1.711 -
1.712 - // add ip/tcp stack to nodes.
1.713 - InternetStackHelper internet;
1.714 - internet.Install (c0);
1.715 -
1.716 - // Later, we add IP addresses.
1.717 - Ipv4AddressHelper ipv4;
1.718 - ipv4.SetBase ("10.1.0.0", "255.255.255.0");
1.719 - Ipv4InterfaceContainer ifaces = ipv4.Assign (dev0);
1.720 -
1.721 - // Configure the apps.
1.722 - uint16_t servPort = 32;
1.723 -
1.724 -
1.725 - // setup Rx side using ns3::Node "c0[1]" to listen for ANY:servPort
1.726 - Ptr<TalkerApp> sink = CreateObject<TalkerApp_sub>();
1.727 - sink->ConfRecv (c0.Get (1),
1.728 - InetSocketAddress (Ipv4Address::GetAny (), servPort));
1.729 - sink->Start (Seconds (0.0)); // somehow we get by without a Stop. bad form?
1.730 -
1.731 - // setup Tx side using ns3::Node "c0[0]" to talk to "c0[1]":servPort
1.732 - Ptr<TalkerApp> source = CreateObject<TalkerApp_sub>();
1.733 - source->ConfSend (c0.Get (0),
1.734 - InetSocketAddress (ifaces.GetAddress (1),
1.735 - servPort));
1.736 - source->Start (Seconds (0.0));
1.737 -
1.738 - // 10 sec is an eternity for this case, we should be done by then.
1.739 - Simulator::Stop (Seconds (10));
1.740 -
1.741 -
1.742 - // For regression use only output ascii and pcap traces.
1.743 -#ifdef REGRESSION_MODE
1.744 - std::ofstream ascii;
1.745 - ascii.open ("tcp-2way.tr");
1.746 - PointToPointHelper::EnableAsciiAll (ascii);
1.747 - PointToPointHelper::EnablePcapAll ("tcp-2way");
1.748 -#endif
1.749 -
1.750 - /*
1.751 - * Now lets schedule some packets and go. For scheduling packets
1.752 - * we have to be careful not to do the backchannel too early or
1.753 - * we try to use a socket that doesn't yet exist since on the Rx
1.754 - * side the socket is created as part of the normal Tx->Rx connection
1.755 - * setup.
1.756 - *
1.757 - * The delay of 40ms was by trial and error and seems good enough. It
1.758 - * would be nice to know what the bounds are and why....
1.759 - */
1.760 -
1.761 - char tagchar = 'A'; // the fill character in case we fill in SendPacket.
1.762 -
1.763 - Time d2t = MilliSeconds(40); /* rate to change time offset (dt) so packets
1.764 - * are sent in order (Tx->Rx, Rx->Tx for a given
1.765 - * size over a range of sizes).*/
1.766 -
1.767 - Time dt = MilliSeconds(0); /* ns3 doesn't take absolute times, but times
1.768 - * relative to Simulator::Now() */
1.769 -
1.770 - uint32_t size = 0;
1.771 - source->ScheduleSendPacket (dt, tagchar, size);
1.772 - dt += d2t;
1.773 - ++tagchar;
1.774 - sink->ScheduleSendPacket (dt, tagchar, size);
1.775 - for (size = 1; size <= 1000000; size *= 10) {
1.776 - dt += d2t;
1.777 - ++tagchar;
1.778 - source->ScheduleSendPacket (dt, tagchar, size);
1.779 - dt += d2t;
1.780 - ++tagchar;
1.781 - sink->ScheduleSendPacket (dt, tagchar, size);
1.782 - }
1.783 -
1.784 - // Release the Hounds!!
1.785 - Simulator::Run ();
1.786 - Simulator::Destroy ();
1.787 - fileOut.close();
1.788 -}
2.1 --- a/examples/wscript Sat Aug 09 10:52:36 2008 -0700
2.2 +++ b/examples/wscript Sun Aug 10 15:45:27 2008 -0400
2.3 @@ -60,10 +60,6 @@
2.4 ['point-to-point', 'internet-stack'])
2.5 obj.source = 'tcp-errors.cc'
2.6
2.7 - obj = bld.create_ns3_program('tcp-2way',
2.8 - ['point-to-point', 'internet-stack'])
2.9 - obj.source = 'tcp-2way.cc'
2.10 -
2.11 obj = bld.create_ns3_program('tcp-star-server',
2.12 ['point-to-point', 'internet-stack'])
2.13 obj.source = 'tcp-star-server.cc'