TCPExampleApp.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2010 Karlsruhe Institute of Technology (KIT),
00003 //                    Institute of Telematics
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 //
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 //
00019 
00025 #include <string>
00026 
00027 #include "UnderlayConfigurator.h"
00028 #include "GlobalStatistics.h"
00029 #include "GlobalNodeList.h"
00030 #include "IPAddressResolver.h"
00031 
00032 using namespace std;
00033 
00034 #include "TCPExampleApp.h"
00035 
00036 Define_Module(TCPExampleApp);
00037 
00038 TCPExampleApp::TCPExampleApp()
00039 {
00040     timerMsg = NULL;
00041 }
00042 
00043 TCPExampleApp::~TCPExampleApp()
00044 {
00045     cancelAndDelete(timerMsg);
00046 }
00047 
00048 void TCPExampleApp::initializeApp(int stage)
00049 {
00050     if (stage != MIN_STAGE_APP) {
00051         return;
00052     }
00053 
00054     // copy the module parameter values to our own variables
00055     sendPeriod = par("sendPeriod");
00056 
00057     // initialize our statistics variables
00058     numSent = 0;
00059     numReceived = 0;
00060 
00061     // tell the GUI to display our variables
00062     WATCH(numSent);
00063     WATCH(numReceived);
00064 
00065     // start our timer
00066     timerMsg = new cMessage("Periodic timer");
00067 
00068     // set up and listen on tcp
00069     bindAndListenTcp(24000);
00070 
00071     // first node which was created starts with PING-PONG messaging
00072     if (globalNodeList->getNumNodes() == 1) {
00073         scheduleAt(simTime() + SimTime::parse("20s"), timerMsg);
00074     }
00075 }
00076 
00077 
00078 void TCPExampleApp::finishApp()
00079 {
00080     globalStatistics->addStdDev("TCPExampleApp: Sent packets", numSent);
00081     globalStatistics->addStdDev("TCPExampleApp: Received packets", numReceived);
00082 }
00083 
00084 
00085 void TCPExampleApp::handleTimerEvent(cMessage* msg)
00086 {
00087     if (msg == timerMsg) {
00088         // if the simulator is still busy creating the network,
00089         // let's wait a bit longer
00090         if (underlayConfigurator->isInInitPhase()) {
00091             scheduleAt(simTime() + sendPeriod, timerMsg);
00092             return;
00093         }
00094 
00095         // do the same, if the node is the only one alive
00096         if (globalNodeList->getNumNodes() == 1){
00097             scheduleAt(simTime() + sendPeriod, timerMsg);
00098             return;
00099         }
00100 
00101         // get the address of one of the other nodes
00102         TransportAddress* addr = globalNodeList->getRandomAliveNode();
00103         while (thisNode.getIp().equals(addr->getIp())) {
00104             addr = globalNodeList->getRandomAliveNode();
00105         }
00106 
00107         // create a PING message
00108         TCPExampleMessage *TCPMsg = new TCPExampleMessage();
00109         TCPMsg->setType(TCPEXMSG_PING); // set the message type to PING
00110         TCPMsg->setSenderAddress(thisNode); // set the sender address to our own
00111         TCPMsg->setByteLength(100); // set the message length to 100 bytes
00112 
00113         RECORD_STATS(numSent++); // update statistics
00114 
00115         // connect and send message
00116         TransportAddress remoteAddress = TransportAddress(addr->getIp(), 24000);
00117         establishTcpConnection(remoteAddress);
00118         sendTcpData(TCPMsg, remoteAddress);
00119 
00120         // user output
00121         EV << thisNode.getIp() << ": Connecting to "<< addr->getIp()
00122            << " and sending PING."<< std::endl;
00123     }
00124 }
00125 
00126 void TCPExampleApp::handleDataReceived(TransportAddress address, cPacket* msg, bool urgent)
00127 {
00128         // *redefine* to perform or schedule next sending
00129         TCPExampleMessage *TCPMsg = dynamic_cast<TCPExampleMessage*>(msg);
00130 
00131         RECORD_STATS(numReceived++);
00132 
00133         if (TCPMsg && TCPMsg->getType() == TCPEXMSG_PING){
00134             // create PONG message
00135             TCPExampleMessage *respMsg = new TCPExampleMessage();
00136             respMsg->setType(TCPEXMSG_PONG); // set the message type to PONG
00137             respMsg->setSenderAddress(thisNode); // set the sender address to our own
00138             respMsg->setByteLength(100);
00139 
00140             sendTcpData(respMsg, address);
00141 
00142             RECORD_STATS(numSent++);
00143 
00144             // user output
00145             EV << thisNode.getIp() << ": Got PING from "
00146                << TCPMsg->getSenderAddress().getIp() << ", sending PONG!"
00147                << std::endl;
00148 
00149         } else if (TCPMsg && TCPMsg->getType() == TCPEXMSG_PONG){
00150             // user output
00151             EV << thisNode.getIp() << ": Got PONG reply! Closing connection." << std::endl;
00152 
00153             // dialog successfully transmitted, close connection
00154             closeTcpConnection(address);
00155         }
00156 
00157         delete msg;
00158 }
00159 
00160 void TCPExampleApp::handleConnectionEvent(EvCode code, TransportAddress address)
00161 {
00162     if (code == PEER_CLOSED) {
00163         scheduleAt(simTime() + sendPeriod, timerMsg);
00164     } else {
00165         BaseTcpSupport::handleConnectionEvent(code, address);
00166     }
00167 }