|
INET Framework for OMNeT++/OMNEST
|
00001 // 00002 // Copyright (C) 2004 Andras Varga 00003 // 00004 // This program is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public License 00006 // as published by the Free Software Foundation; either version 2 00007 // of the License, or (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU Lesser General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU Lesser General Public License 00015 // along with this program; if not, see <http://www.gnu.org/licenses/>. 00016 // 00017 00018 00019 #include "TCPBasicClientApp.h" 00020 00021 00022 #define MSGKIND_CONNECT 0 00023 #define MSGKIND_SEND 1 00024 00025 00026 Define_Module(TCPBasicClientApp); 00027 00028 TCPBasicClientApp::TCPBasicClientApp() 00029 { 00030 timeoutMsg = NULL; 00031 } 00032 00033 TCPBasicClientApp::~TCPBasicClientApp() 00034 { 00035 cancelAndDelete(timeoutMsg); 00036 } 00037 00038 void TCPBasicClientApp::initialize() 00039 { 00040 TCPGenericCliAppBase::initialize(); 00041 00042 timeoutMsg = new cMessage("timer"); 00043 00044 numRequestsToSend = 0; 00045 earlySend = false; // TBD make it parameter 00046 WATCH(numRequestsToSend); 00047 WATCH(earlySend); 00048 00049 timeoutMsg->setKind(MSGKIND_CONNECT); 00050 scheduleAt((simtime_t)par("startTime"), timeoutMsg); 00051 } 00052 00053 void TCPBasicClientApp::sendRequest() 00054 { 00055 EV << "sending request, " << numRequestsToSend-1 << " more to go\n"; 00056 00057 long requestLength = par("requestLength"); 00058 long replyLength = par("replyLength"); 00059 if (requestLength<1) requestLength=1; 00060 if (replyLength<1) replyLength=1; 00061 00062 sendPacket(requestLength, replyLength); 00063 } 00064 00065 void TCPBasicClientApp::handleTimer(cMessage *msg) 00066 { 00067 switch (msg->getKind()) 00068 { 00069 case MSGKIND_CONNECT: 00070 EV << "starting session\n"; 00071 connect(); // active OPEN 00072 00073 // significance of earlySend: if true, data will be sent already 00074 // in the ACK of SYN, otherwise only in a separate packet (but still 00075 // immediately) 00076 if (earlySend) 00077 sendRequest(); 00078 break; 00079 00080 case MSGKIND_SEND: 00081 sendRequest(); 00082 numRequestsToSend--; 00083 // no scheduleAt(): next request will be sent when reply to this one 00084 // arrives (see socketDataArrived()) 00085 break; 00086 } 00087 } 00088 00089 void TCPBasicClientApp::socketEstablished(int connId, void *ptr) 00090 { 00091 TCPGenericCliAppBase::socketEstablished(connId, ptr); 00092 00093 // determine number of requests in this session 00094 numRequestsToSend = (long) par("numRequestsPerSession"); 00095 if (numRequestsToSend<1) numRequestsToSend=1; 00096 00097 // perform first request if not already done (next one will be sent when reply arrives) 00098 if (!earlySend) 00099 sendRequest(); 00100 numRequestsToSend--; 00101 } 00102 00103 void TCPBasicClientApp::socketDataArrived(int connId, void *ptr, cPacket *msg, bool urgent) 00104 { 00105 TCPGenericCliAppBase::socketDataArrived(connId, ptr, msg, urgent); 00106 00107 if (numRequestsToSend>0) 00108 { 00109 EV << "reply arrived\n"; 00110 timeoutMsg->setKind(MSGKIND_SEND); 00111 scheduleAt(simTime()+(simtime_t)par("thinkTime"), timeoutMsg); 00112 } 00113 else 00114 { 00115 EV << "reply to last request arrived, closing session\n"; 00116 close(); 00117 } 00118 } 00119 00120 void TCPBasicClientApp::socketClosed(int connId, void *ptr) 00121 { 00122 TCPGenericCliAppBase::socketClosed(connId, ptr); 00123 00124 // start another session after a delay 00125 timeoutMsg->setKind(MSGKIND_CONNECT); 00126 scheduleAt(simTime()+(simtime_t)par("idleInterval"), timeoutMsg); 00127 } 00128 00129 void TCPBasicClientApp::socketFailure(int connId, void *ptr, int code) 00130 { 00131 TCPGenericCliAppBase::socketFailure(connId, ptr, code); 00132 00133 // reconnect after a delay 00134 timeoutMsg->setKind(MSGKIND_CONNECT); 00135 scheduleAt(simTime()+(simtime_t)par("reconnectInterval"), timeoutMsg); 00136 } 00137