INET Framework for OMNeT++/OMNEST
TCPGenericSrvApp Class Reference

#include <TCPGenericSrvApp.h>

List of all members.

Protected Member Functions

virtual void sendBack (cMessage *msg)
virtual void sendOrSchedule (cMessage *msg, simtime_t delay)
virtual void initialize ()
virtual void handleMessage (cMessage *msg)
virtual void finish ()

Protected Attributes

simtime_t delay
simtime_t maxMsgDelay
long msgsRcvd
long msgsSent
long bytesRcvd
long bytesSent

Detailed Description

Generic server application. It serves requests coming in GenericAppMsg request messages. Clients are usually subclassed from TCPGenericCliAppBase.

See also:
GenericAppMsg, TCPGenericCliAppBase

Member Function Documentation

void TCPGenericSrvApp::finish ( ) [protected, virtual]
{
    EV << getFullPath() << ": sent " << bytesSent << " bytes in " << msgsSent << " packets\n";
    EV << getFullPath() << ": received " << bytesRcvd << " bytes in " << msgsRcvd << " packets\n";

    recordScalar("packets sent", msgsSent);
    recordScalar("packets rcvd", msgsRcvd);
    recordScalar("bytes sent", bytesSent);
    recordScalar("bytes rcvd", bytesRcvd);
}
void TCPGenericSrvApp::handleMessage ( cMessage *  msg) [protected, virtual]
{
    if (msg->isSelfMessage())
    {
        sendBack(msg);
    }
    else if (msg->getKind()==TCP_I_PEER_CLOSED)
    {
        // we'll close too, but only after there's surely no message
        // pending to be sent back in this connection
        msg->setName("close");
        msg->setKind(TCP_C_CLOSE);
        sendOrSchedule(msg,delay+maxMsgDelay);
    }
    else if (msg->getKind()==TCP_I_DATA || msg->getKind()==TCP_I_URGENT_DATA)
    {
        GenericAppMsg *appmsg = dynamic_cast<GenericAppMsg *>(msg);
        if (!appmsg)
            error("Message (%s)%s is not a GenericAppMsg -- "
                  "probably wrong client app, or wrong setting of TCP's "
                  "sendQueueClass/receiveQueueClass parameters "
                  "(try \"TCPMsgBasedSendQueue\" and \"TCPMsgBasedRcvQueue\")",
                  msg->getClassName(), msg->getName());

        msgsRcvd++;
        bytesRcvd += appmsg->getByteLength();

        long requestedBytes = appmsg->getExpectedReplyLength();

        simtime_t msgDelay = appmsg->getReplyDelay();
        if (msgDelay>maxMsgDelay)
            maxMsgDelay = msgDelay;

        bool doClose = appmsg->getServerClose();
        int connId = check_and_cast<TCPCommand *>(appmsg->getControlInfo())->getConnId();

        if (requestedBytes==0)
        {
            delete msg;
        }
        else
        {
            delete appmsg->removeControlInfo();
            TCPSendCommand *cmd = new TCPSendCommand();
            cmd->setConnId(connId);
            appmsg->setControlInfo(cmd);

            // set length and send it back
            appmsg->setKind(TCP_C_SEND);
            appmsg->setByteLength(requestedBytes);
            sendOrSchedule(appmsg, delay+msgDelay);
        }

        if (doClose)
        {
            cMessage *msg = new cMessage("close");
            msg->setKind(TCP_C_CLOSE);
            TCPCommand *cmd = new TCPCommand();
            cmd->setConnId(connId);
            msg->setControlInfo(cmd);
            sendOrSchedule(msg, delay+maxMsgDelay);
        }
    }
    else
    {
        // some indication -- ignore
        delete msg;
    }

    if (ev.isGUI())
    {
        char buf[64];
        sprintf(buf, "rcvd: %ld pks %ld bytes\nsent: %ld pks %ld bytes", msgsRcvd, bytesRcvd, msgsSent, bytesSent);
        getDisplayString().setTagArg("t",0,buf);
    }
}
void TCPGenericSrvApp::initialize ( ) [protected, virtual]
{
    const char *address = par("address");
    int port = par("port");
    delay = par("replyDelay");
    maxMsgDelay = 0;

    msgsRcvd = msgsSent = bytesRcvd = bytesSent = 0;
    WATCH(msgsRcvd);
    WATCH(msgsSent);
    WATCH(bytesRcvd);
    WATCH(bytesSent);

    TCPSocket socket;
    socket.setOutputGate(gate("tcpOut"));
    socket.bind(address[0] ? IPvXAddress(address) : IPvXAddress(), port);
    socket.listen();
}
void TCPGenericSrvApp::sendBack ( cMessage *  msg) [protected, virtual]

Referenced by handleMessage(), and sendOrSchedule().

{
    GenericAppMsg *appmsg = dynamic_cast<GenericAppMsg*>(msg);

    if (appmsg)
    {
        msgsSent++;
        bytesSent += appmsg->getByteLength();

        EV << "sending \"" << appmsg->getName() << "\" to TCP, " << appmsg->getByteLength() << " bytes\n";
    }
    else
    {
        EV << "sending \"" << msg->getName() << "\" to TCP\n";
    }

    send(msg, "tcpOut");
}
void TCPGenericSrvApp::sendOrSchedule ( cMessage *  msg,
simtime_t  delay 
) [protected, virtual]

Referenced by handleMessage().

{
    if (delay==0)
        sendBack(msg);
    else
        scheduleAt(simTime()+delay, msg);
}

Member Data Documentation

long TCPGenericSrvApp::bytesRcvd [protected]

Referenced by finish(), handleMessage(), and initialize().

simtime_t TCPGenericSrvApp::delay [protected]

Referenced by handleMessage(), and initialize().

simtime_t TCPGenericSrvApp::maxMsgDelay [protected]

Referenced by handleMessage(), and initialize().

long TCPGenericSrvApp::msgsRcvd [protected]

Referenced by finish(), handleMessage(), and initialize().


The documentation for this class was generated from the following files: