1 // ANNA - Anna is Not Nothingness Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // http://redmine.teslayout.com/projects/anna-suite
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
17 // * Neither the name of the copyright holder nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
38 Realiza peticiones automaticas sobre el servidor de operaciones aritmeticas.
40 La cadencia de envio de mensajes se establece mediante un temporizador.
41 Los operadores se calculan de forma aleatoria.
43 El servidor de este cliente: server
51 #include <anna/core/core.hpp>
52 #include <anna/app/functions.hpp>
53 #include <anna/comm/comm.hpp>
55 #include <anna/timex/Engine.hpp>
56 #include <anna/timex/Clock.hpp>
58 #include <anna/test/Response.hpp>
59 #include <anna/test/Request.hpp>
61 class Sender : public timex::Clock {
63 Sender () : Clock ("Sender", (Millisecond)1000),
64 a_messageBySecond (0),
66 a_requests ("Request"),
68 a_txMessageCounter (0)
71 void setMessageBySecond (const int messageBySecond) throw () { a_messageBySecond = messageBySecond; }
73 int getTxMessageCounter () const throw () { return a_txMessageCounter; }
76 int a_messageBySecond;
79 int a_txMessageCounter;
80 ThreadData <test::Request> a_requests;
82 bool tick () throw (RuntimeException);
85 class MyCommunicator : public Communicator {
87 MyCommunicator () : Communicator (), a_avgResponseTime (0), a_rxMessageCounter (0), a_responses ("Response") {;}
90 ThreadData <test::Response> a_responses;
91 int a_avgResponseTime;
92 int a_rxMessageCounter;
94 void eventReceiveMessage (ClientSocket &, const Message&)
95 throw (RuntimeException);
97 void eventBreakConnection (const ClientSocket&) throw ();
99 void eventBreakConnection (Server* server) throw () {
100 comm::Communicator::eventBreakConnection (server);
102 void eventBreakConnection (const Service* service) throw () {
103 comm::Communicator::eventBreakConnection (service);
106 static bool isOk (const test::Response& response) throw ();
109 class HeavyClient : public anna::comm::Application {
113 Server* getServer () const throw () { return a_server; }
114 const Sender* getSender () const throw () { return &a_sender; }
117 MyCommunicator a_communicator;
118 timex::Engine a_timeController;
122 void initialize () throw (RuntimeException);
123 void run () throw (RuntimeException);
128 int main (int argc, const char** argv)
130 CommandLine& commandLine (CommandLine::instantiate ());
136 commandLine.initialize (argv, argc);
137 commandLine.verify ();
139 Logger::setLevel (Logger::Information);
140 string traceFile ("client.");
141 traceFile += anna::functions::asString ((int) getpid ());
142 traceFile += ".trace";
143 Logger::initialize ("arithmeticClient", new TraceWriter (traceFile.c_str (),4096000));
147 catch (Exception& ex) {
148 cout << ex.asString () << endl;
154 HeavyClient::HeavyClient () :
155 Application ("arithmeticClient", "Cliente de operaciones aritm�icas", "1.0"),
157 a_timeController ((Millisecond)1000, (Millisecond)250)
159 CommandLine& commandLine (CommandLine::instantiate ());
161 commandLine.add ("p", CommandLine::Argument::Mandatory, "Puerto en el que el servidor atiende respuestas.");
162 commandLine.add ("a", CommandLine::Argument::Mandatory, "Direccin IP Puerto en el que el servidor atiende respuestas.");
163 commandLine.add ("n", CommandLine::Argument::Mandatory, "Numero de mensajes por segundo");
164 commandLine.add ("trace", CommandLine::Argument::Optional, "Nivel de trazas (debug,warning, error,...)");
167 void HeavyClient::initialize ()
168 throw (RuntimeException)
170 CommandLine& cl (CommandLine::instantiate ());
172 Network& network = Network::instantiate ();
174 a_server = network.createServer (cl.getValue ("a"), cl.getIntegerValue ("p"), true);
175 a_sender.setMessageBySecond (cl.getIntegerValue ("n"));
177 if (cl.exists ("trace"))
178 Logger::setLevel (Logger::asLevel (cl.getValue ("trace")));
181 void HeavyClient::run ()
182 throw (RuntimeException)
184 a_timeController.activate (a_sender);
186 a_communicator.accept ();
189 void MyCommunicator::eventReceiveMessage (ClientSocket&, const Message& message)
190 throw (RuntimeException)
192 test::Response& response = a_responses.get ();
193 response.decode (message.getBody ());
195 const anna::Millisecond now = anna::functions::millisecond ();
196 const int delay = now - (Millisecond) response.initTime;
198 if (delay > 0 && isOk (response) == true) {
199 a_rxMessageCounter ++;
200 a_avgResponseTime += delay;
203 string msg = anna::functions::asString (
204 "%d %c %d = %d", response.x, response.op, response.y, response.result
206 msg += anna::functions::asText (" | Delay: ", delay);
207 Logger::information (msg, ANNA_FILE_LOCATION);
212 string msg = anna::functions::asString (
213 "Flip: %d %c %d = %d", response.x, response.op, response.y, response.result
215 msg += anna::functions::asText (" | Message: ", message.getBody ());
216 msg += anna::functions::asText (" | Delay: ", delay);
217 Logger::warning (msg, ANNA_FILE_LOCATION);
222 void MyCommunicator::eventBreakConnection (const ClientSocket& clientSocket)
225 if (a_rxMessageCounter == 0)
229 HeavyClient& app = static_cast <HeavyClient&> (anna::app::functions::getApp ());
230 string msg ("Tiempo medio respuesta: ");
231 msg += anna::functions::asString (a_avgResponseTime / a_rxMessageCounter);
233 msg += anna::functions::asText (" | Rx: ", a_rxMessageCounter);
234 msg += anna::functions::asText (" | Tx: ", app.getSender ()->getTxMessageCounter ());
235 Logger::notice (msg, ANNA_FILE_LOCATION);
237 cout << msg << endl << endl;
240 comm::Communicator::eventBreakConnection (clientSocket);
243 bool MyCommunicator::isOk (const test::Response& response)
246 if (response.op != '+' && response.op != '-' && response.op != '*' && response.op != '/')
251 switch (response.op) {
253 result = response.x + response.y;
256 result = response.x - response.y;
259 result = response.x * response.y;
262 result = (response.y != 0) ? (response.x / response.y): 0;
266 return result == response.result;
270 throw (RuntimeException)
272 Server* server = static_cast <HeavyClient&> (anna::app::functions::getApp ()).getServer ();
273 Communicator* communicator = anna::app::functions::component <Communicator> (ANNA_FILE_LOCATION);
275 if (a_errorCounter > 10) {
276 Logger::warning ("Terminado por errores continuos en la conexion", ANNA_FILE_LOCATION);
278 communicator->requestStop ();
280 catch (RuntimeException& ex) {
286 test::Request& request = a_requests.get ();
288 for (int n = 0; n < a_messageBySecond && communicator->hasRequestedStop () == false; n ++) {
290 request.x = rand () % 1000;
291 request.y = rand () % 1000;
292 request.initTime = anna::functions::millisecond ();
295 server->send (request);
296 a_txMessageCounter ++;
298 catch (RuntimeException& ex) {
299 string msg (ex.getText ());
300 msg += anna::functions::asText (" | ErrorCounter: ", ++ a_errorCounter);
301 Logger::warning (msg, ANNA_FILE_LOCATION);