TCPGenericSrvApp.cc

Go to the documentation of this file.
00001 //
00002 // Copyright 2004 Andras Varga
00003 //
00004 // This library is free software, you can redistribute it and/or modify
00005 // it under  the terms of the GNU Lesser General Public License
00006 // as published by the Free Software Foundation;
00007 // either version 2 of the License, or any later version.
00008 // The library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00011 // See the GNU Lesser General Public License for more details.
00012 //
00013 
00014 
00015 #include "TCPGenericSrvApp.h"
00016 #include "TCPSocket.h"
00017 #include "TCPCommand_m.h"
00018 #include "GenericAppMsg_m.h"
00019 
00020 
00021 Define_Module(TCPGenericSrvApp);
00022 
00023 void TCPGenericSrvApp::initialize()
00024 {
00025     const char *address = par("address");
00026     int port = par("port");
00027     delay = par("replyDelay");
00028     maxMsgDelay = 0;
00029 
00030     msgsRcvd = msgsSent = bytesRcvd = bytesSent = 0;
00031     WATCH(msgsRcvd);
00032     WATCH(msgsSent);
00033     WATCH(bytesRcvd);
00034     WATCH(bytesSent);
00035 
00036     TCPSocket socket;
00037     socket.setOutputGate(gate("tcpOut"));
00038     socket.bind(address[0] ? IPvXAddress(address) : IPvXAddress(), port);
00039     socket.listen();
00040 }
00041 
00042 void TCPGenericSrvApp::sendOrSchedule(cMessage *msg, simtime_t delay)
00043 {
00044     if (delay==0)
00045         sendBack(msg);
00046     else
00047         scheduleAt(simTime()+delay, msg);
00048 }
00049 
00050 void TCPGenericSrvApp::sendBack(cMessage *msg)
00051 {
00052     GenericAppMsg *appmsg = dynamic_cast<GenericAppMsg*>(msg);
00053 
00054     if (appmsg)
00055     {
00056         msgsSent++;
00057         bytesSent += appmsg->getByteLength();
00058 
00059         EV << "sending \"" << appmsg->getName() << "\" to TCP, " << appmsg->getByteLength() << " bytes\n";
00060     }
00061     else
00062     {
00063         EV << "sending \"" << msg->getName() << "\" to TCP\n";
00064     }
00065 
00066     send(msg, "tcpOut");
00067 }
00068 
00069 void TCPGenericSrvApp::handleMessage(cMessage *msg)
00070 {
00071     if (msg->isSelfMessage())
00072     {
00073         sendBack(msg);
00074     }
00075     else if (msg->getKind()==TCP_I_PEER_CLOSED)
00076     {
00077         // we'll close too, but only after there's surely no message
00078         // pending to be sent back in this connection
00079         msg->setName("close");
00080         msg->setKind(TCP_C_CLOSE);
00081         sendOrSchedule(msg,delay+maxMsgDelay);
00082     }
00083     else if (msg->getKind()==TCP_I_DATA || msg->getKind()==TCP_I_URGENT_DATA)
00084     {
00085         GenericAppMsg *appmsg = dynamic_cast<GenericAppMsg *>(msg);
00086         if (!appmsg)
00087             error("Message (%s)%s is not a GenericAppMsg -- "
00088                   "probably wrong client app, or wrong setting of TCP's "
00089                   "sendQueueClass/receiveQueueClass parameters "
00090                   "(try \"TCPMsgBasedSendQueue\" and \"TCPMsgBasedRcvQueue\")",
00091                   msg->getClassName(), msg->getName());
00092 
00093         msgsRcvd++;
00094         bytesRcvd += appmsg->getByteLength();
00095 
00096         long requestedBytes = appmsg->getExpectedReplyLength();
00097 
00098         simtime_t msgDelay = appmsg->getReplyDelay();
00099         if (msgDelay>maxMsgDelay)
00100             maxMsgDelay = msgDelay;
00101 
00102         bool doClose = appmsg->getServerClose();
00103         int connId = check_and_cast<TCPCommand *>(appmsg->getControlInfo())->getConnId();
00104 
00105         if (requestedBytes==0)
00106         {
00107             delete msg;
00108         }
00109         else
00110         {
00111             delete appmsg->removeControlInfo();
00112             TCPSendCommand *cmd = new TCPSendCommand();
00113             cmd->setConnId(connId);
00114             appmsg->setControlInfo(cmd);
00115 
00116             // set length and send it back
00117             appmsg->setKind(TCP_C_SEND);
00118             appmsg->setByteLength(requestedBytes);
00119             sendOrSchedule(appmsg, delay+msgDelay);
00120         }
00121 
00122         if (doClose)
00123         {
00124             cMessage *msg = new cMessage("close");
00125             msg->setKind(TCP_C_CLOSE);
00126             TCPCommand *cmd = new TCPCommand();
00127             cmd->setConnId(connId);
00128             msg->setControlInfo(cmd);
00129             sendOrSchedule(msg, delay+maxMsgDelay);
00130         }
00131     }
00132     else
00133     {
00134         // some indication -- ignore
00135         delete msg;
00136     }
00137 
00138     if (ev.isGUI())
00139     {
00140         char buf[64];
00141         sprintf(buf, "rcvd: %ld pks %ld bytes\nsent: %ld pks %ld bytes", msgsRcvd, bytesRcvd, msgsSent, bytesSent);
00142         getDisplayString().setTagArg("t",0,buf);
00143     }
00144 }
00145 
00146 void TCPGenericSrvApp::finish()
00147 {
00148     EV << getFullPath() << ": sent " << bytesSent << " bytes in " << msgsSent << " packets\n";
00149     EV << getFullPath() << ": received " << bytesRcvd << " bytes in " << msgsRcvd << " packets\n";
00150 
00151     recordScalar("packets sent", msgsSent);
00152     recordScalar("packets rcvd", msgsRcvd);
00153     recordScalar("bytes sent", bytesSent);
00154     recordScalar("bytes rcvd", bytesRcvd);
00155 }