OverSim
TCPExampleApp.cc
Go to the documentation of this file.
1 //
2 // Copyright (C) 2010 Karlsruhe Institute of Technology (KIT),
3 // Institute of Telematics
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
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
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 //
19 
25 #include <string>
26 
27 #include "UnderlayConfigurator.h"
28 #include "GlobalStatistics.h"
29 #include "GlobalNodeList.h"
30 #include "IPAddressResolver.h"
31 #include "BootstrapList.h"
32 
33 using namespace std;
34 
35 #include "TCPExampleApp.h"
36 
38 
40 {
41  timerMsg = NULL;
42 }
43 
45 {
46  cancelAndDelete(timerMsg);
47 }
48 
50 {
51  if (stage != MIN_STAGE_APP) {
52  return;
53  }
54 
55  // copy the module parameter values to our own variables
56  sendPeriod = par("sendPeriod");
57 
58  // initialize our statistics variables
59  numSent = 0;
60  numReceived = 0;
61 
62  // tell the GUI to display our variables
63  WATCH(numSent);
64  WATCH(numReceived);
65 
66  // start our timer
67  timerMsg = new cMessage("Periodic timer");
68 
69  // set up and listen on tcp
70  bindAndListenTcp(24000);
71 
72  BootstrapList* bootstrapList = check_and_cast<BootstrapList*>(
73  overlay->getCompModule(BOOTSTRAPLIST_COMP));
74  bootstrapList->registerBootstrapNode(thisNode);
75 
76  // first node which was created starts with PING-PONG messaging
77  if (globalNodeList->getNumNodes() == 1) {
78  scheduleAt(simTime() + SimTime::parse("20s"), timerMsg);
79  }
80 }
81 
82 
84 {
85  globalStatistics->addStdDev("TCPExampleApp: Sent packets", numSent);
86  globalStatistics->addStdDev("TCPExampleApp: Received packets", numReceived);
87 }
88 
89 
91 {
92  if (msg == timerMsg) {
93  // if the simulator is still busy creating the network,
94  // let's wait a bit longer
95  if (underlayConfigurator->isInInitPhase()) {
96  scheduleAt(simTime() + sendPeriod, timerMsg);
97  return;
98  }
99 
100  // do the same, if the node is the only one alive
101  if (globalNodeList->getNumNodes() == 1){
102  scheduleAt(simTime() + sendPeriod, timerMsg);
103  return;
104  }
105 
106  // get the address of one of the other nodes
107  TransportAddress* addr = globalNodeList->getRandomAliveNode();
108  while ((addr != NULL) && (thisNode.getIp().equals(addr->getIp()))) {
109  addr = globalNodeList->getRandomAliveNode();
110  }
111 
112  assert(addr != NULL);
113 
114  // create a PING message
115  TCPExampleMessage *TCPMsg = new TCPExampleMessage();
116  TCPMsg->setType(TCPEXMSG_PING); // set the message type to PING
117  TCPMsg->setSenderAddress(thisNode); // set the sender address to our own
118  TCPMsg->setByteLength(100); // set the message length to 100 bytes
119 
120  RECORD_STATS(numSent++); // update statistics
121 
122  // connect and send message
123  TransportAddress remoteAddress = TransportAddress(addr->getIp(), 24000);
124  establishTcpConnection(remoteAddress);
125  sendTcpData(TCPMsg, remoteAddress);
126 
127  // user output
128  EV << thisNode.getIp() << ": Connecting to "<< addr->getIp()
129  << " and sending PING."<< std::endl;
130  }
131 }
132 
133 void TCPExampleApp::handleDataReceived(TransportAddress address, cPacket* msg, bool urgent)
134 {
135  // *redefine* to perform or schedule next sending
136  TCPExampleMessage *TCPMsg = dynamic_cast<TCPExampleMessage*>(msg);
137 
138  RECORD_STATS(numReceived++);
139 
140  if (TCPMsg && TCPMsg->getType() == TCPEXMSG_PING){
141  // create PONG message
142  TCPExampleMessage *respMsg = new TCPExampleMessage();
143  respMsg->setType(TCPEXMSG_PONG); // set the message type to PONG
144  respMsg->setSenderAddress(thisNode); // set the sender address to our own
145  respMsg->setByteLength(100);
146 
147  sendTcpData(respMsg, address);
148 
149  RECORD_STATS(numSent++);
150 
151  // user output
152  EV << thisNode.getIp() << ": Got PING from "
153  << TCPMsg->getSenderAddress().getIp() << ", sending PONG!"
154  << std::endl;
155 
156  } else if (TCPMsg && TCPMsg->getType() == TCPEXMSG_PONG){
157  // user output
158  EV << thisNode.getIp() << ": Got PONG reply! Closing connection." << std::endl;
159 
160  // dialog successfully transmitted, close connection
161  closeTcpConnection(address);
162  }
163 
164  delete msg;
165 }
166 
168 {
169  if (code == PEER_CLOSED) {
170  scheduleAt(simTime() + sendPeriod, timerMsg);
171  } else {
173  }
174 }