|
INET Framework for OMNeT++/OMNEST
|
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 }