1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
10 Realiza peticiones automaticas sobre el servidor de operaciones aritmeticas.
12 La cadencia de envio de mensajes se establece mediante un temporizador.
13 Los operadores se calculan de forma aleatoria.
15 El servidor de este cliente: server
23 #include <anna/core/core.hpp>
24 #include <anna/app/functions.hpp>
25 #include <anna/comm/comm.hpp>
27 #include <anna/timex/Engine.hpp>
28 #include <anna/timex/Clock.hpp>
30 #include <anna/test/Response.hpp>
31 #include <anna/test/Request.hpp>
33 class Sender : public anna::timex::Clock {
35 Sender () : Clock ("Sender", (Millisecond)1000),
36 a_messageBySecond (0),
38 a_requests ("Request"),
40 a_txMessageCounter (0)
43 void setMessageBySecond (const int messageBySecond) throw () { a_messageBySecond = messageBySecond; }
45 int getTxMessageCounter () const throw () { return a_txMessageCounter; }
48 int a_messageBySecond;
51 int a_txMessageCounter;
52 ThreadData <test::Request> a_requests;
54 bool tick () throw (RuntimeException);
57 class MyCommunicator : public Communicator {
59 MyCommunicator () : Communicator (), a_avgResponseTime (0), a_rxMessageCounter (0), a_responses ("Response") {;}
62 ThreadData <test::Response> a_responses;
63 int a_avgResponseTime;
64 int a_rxMessageCounter;
66 void eventReceiveMessage (ClientSocket &, const Message&)
67 throw (RuntimeException);
69 void eventBreakConnection (const ClientSocket&) throw ();
71 void eventBreakConnection (Server* server) throw () {
72 comm::Communicator::eventBreakConnection (server);
74 void eventBreakConnection (const Service* service) throw () {
75 comm::Communicator::eventBreakConnection (service);
78 static bool isOk (const test::Response& response) throw ();
81 class HeavyClient : public anna::comm::Application {
85 Server* getServer () const throw () { return a_server; }
86 const Sender* getSender () const throw () { return &a_sender; }
89 MyCommunicator a_communicator;
90 anna::timex::Engine a_timeController;
94 void initialize () throw (RuntimeException);
95 void run () throw (RuntimeException);
100 int main (int argc, const char** argv)
102 CommandLine& commandLine (CommandLine::instantiate ());
108 commandLine.initialize (argv, argc);
109 commandLine.verify ();
111 Logger::setLevel (Logger::Information);
112 string traceFile ("client.");
113 traceFile += anna::functions::asString ((int) getpid ());
114 traceFile += ".trace";
115 Logger::initialize ("arithmeticClient", new TraceWriter (traceFile.c_str (),4096000));
119 catch (Exception& ex) {
120 cout << ex.asString () << endl;
126 HeavyClient::HeavyClient () :
127 Application ("arithmeticClient", "Cliente de operaciones aritm�icas", "1.0"),
129 a_timeController ((Millisecond)1000, (Millisecond)250)
131 CommandLine& commandLine (CommandLine::instantiate ());
133 commandLine.add ("p", CommandLine::Argument::Mandatory, "Puerto en el que el servidor atiende respuestas.");
134 commandLine.add ("a", CommandLine::Argument::Mandatory, "Direccin IP Puerto en el que el servidor atiende respuestas.");
135 commandLine.add ("n", CommandLine::Argument::Mandatory, "Numero de mensajes por segundo");
136 commandLine.add ("trace", CommandLine::Argument::Optional, "Nivel de trazas (debug,warning, error,...)");
139 void HeavyClient::initialize ()
140 throw (RuntimeException)
142 CommandLine& cl (CommandLine::instantiate ());
144 Network& network = Network::instantiate ();
146 a_server = network.createServer (cl.getValue ("a"), cl.getIntegerValue ("p"), true);
147 a_sender.setMessageBySecond (cl.getIntegerValue ("n"));
149 if (cl.exists ("trace"))
150 Logger::setLevel (Logger::asLevel (cl.getValue ("trace")));
153 void HeavyClient::run ()
154 throw (RuntimeException)
156 a_timeController.activate (a_sender);
158 a_communicator.accept ();
161 void MyCommunicator::eventReceiveMessage (ClientSocket&, const Message& message)
162 throw (RuntimeException)
164 test::Response& response = a_responses.get ();
165 response.decode (message.getBody ());
167 const anna::Millisecond now = anna::functions::millisecond ();
168 const int delay = now - (Millisecond) response.initTime;
170 if (delay > 0 && isOk (response) == true) {
171 a_rxMessageCounter ++;
172 a_avgResponseTime += delay;
175 string msg = anna::functions::asString (
176 "%d %c %d = %d", response.x, response.op, response.y, response.result
178 msg += anna::functions::asText (" | Delay: ", delay);
179 Logger::information (msg, ANNA_FILE_LOCATION);
184 string msg = anna::functions::asString (
185 "Flip: %d %c %d = %d", response.x, response.op, response.y, response.result
187 msg += anna::functions::asText (" | Message: ", message.getBody ());
188 msg += anna::functions::asText (" | Delay: ", delay);
189 Logger::warning (msg, ANNA_FILE_LOCATION);
194 void MyCommunicator::eventBreakConnection (const ClientSocket& clientSocket)
197 if (a_rxMessageCounter == 0)
201 HeavyClient& app = static_cast <HeavyClient&> (anna::app::functions::getApp ());
202 string msg ("Tiempo medio respuesta: ");
203 msg += anna::functions::asString (a_avgResponseTime / a_rxMessageCounter);
205 msg += anna::functions::asText (" | Rx: ", a_rxMessageCounter);
206 msg += anna::functions::asText (" | Tx: ", app.getSender ()->getTxMessageCounter ());
207 Logger::notice (msg, ANNA_FILE_LOCATION);
209 cout << msg << endl << endl;
212 comm::Communicator::eventBreakConnection (clientSocket);
215 bool MyCommunicator::isOk (const test::Response& response)
218 if (response.op != '+' && response.op != '-' && response.op != '*' && response.op != '/')
223 switch (response.op) {
225 result = response.x + response.y;
228 result = response.x - response.y;
231 result = response.x * response.y;
234 result = (response.y != 0) ? (response.x / response.y): 0;
238 return result == response.result;
242 throw (RuntimeException)
244 Server* server = static_cast <HeavyClient&> (anna::app::functions::getApp ()).getServer ();
245 Communicator* communicator = anna::app::functions::component <Communicator> (ANNA_FILE_LOCATION);
247 if (a_errorCounter > 10) {
248 Logger::warning ("Terminado por errores continuos en la conexion", ANNA_FILE_LOCATION);
250 communicator->requestStop ();
252 catch (RuntimeException& ex) {
258 test::Request& request = a_requests.get ();
260 for (int n = 0; n < a_messageBySecond && communicator->hasRequestedStop () == false; n ++) {
262 request.x = rand () % 1000;
263 request.y = rand () % 1000;
264 request.initTime = anna::functions::millisecond ();
267 server->send (request);
268 a_txMessageCounter ++;
270 catch (RuntimeException& ex) {
271 string msg (ex.getText ());
272 msg += anna::functions::asText (" | ErrorCounter: ", ++ a_errorCounter);
273 Logger::warning (msg, ANNA_FILE_LOCATION);