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);
71 using Communicator::eventBreakConnection;
73 void eventBreakConnection (const ClientSocket&) throw ();
75 void eventBreakConnection (Server* server) throw () {
76 comm::Communicator::eventBreakConnection (server);
78 void eventBreakConnection (const Service* service) throw () {
79 comm::Communicator::eventBreakConnection (service);
82 static bool isOk (const test::Response& response) throw ();
85 class HeavyClient : public anna::comm::Application {
89 Server* getServer () const throw () { return a_server; }
90 const Sender* getSender () const throw () { return &a_sender; }
93 MyCommunicator a_communicator;
94 anna::timex::Engine a_timeController;
98 void initialize () throw (RuntimeException);
99 void run () throw (RuntimeException);
104 int main (int argc, const char** argv)
106 CommandLine& commandLine (CommandLine::instantiate ());
112 commandLine.initialize (argv, argc);
113 commandLine.verify ();
115 Logger::setLevel (Logger::Information);
116 string traceFile ("client.");
117 traceFile += anna::functions::asString ((int) getpid ());
118 traceFile += ".trace";
119 Logger::initialize ("arithmeticClient", new TraceWriter (traceFile.c_str (),4096000));
123 catch (Exception& ex) {
124 cout << ex.asString () << endl;
130 HeavyClient::HeavyClient () :
131 Application ("arithmeticClient", "Cliente de operaciones aritm�icas", "1.0"),
133 a_timeController ((Millisecond)1000, (Millisecond)250)
135 CommandLine& commandLine (CommandLine::instantiate ());
137 commandLine.add ("p", CommandLine::Argument::Mandatory, "Puerto en el que el servidor atiende respuestas.");
138 commandLine.add ("a", CommandLine::Argument::Mandatory, "Direccin IP Puerto en el que el servidor atiende respuestas.");
139 commandLine.add ("n", CommandLine::Argument::Mandatory, "Numero de mensajes por segundo");
140 commandLine.add ("trace", CommandLine::Argument::Optional, "Nivel de trazas (debug,warning, error,...)");
143 void HeavyClient::initialize ()
144 throw (RuntimeException)
146 CommandLine& cl (CommandLine::instantiate ());
148 Network& network = Network::instantiate ();
150 a_server = network.createServer (cl.getValue ("a"), cl.getIntegerValue ("p"), true);
151 a_sender.setMessageBySecond (cl.getIntegerValue ("n"));
153 if (cl.exists ("trace"))
154 Logger::setLevel (Logger::asLevel (cl.getValue ("trace")));
157 void HeavyClient::run ()
158 throw (RuntimeException)
160 a_timeController.activate (a_sender);
162 a_communicator.accept ();
165 void MyCommunicator::eventReceiveMessage (ClientSocket&, const Message& message)
166 throw (RuntimeException)
168 test::Response& response = a_responses.get ();
169 response.decode (message.getBody ());
171 const anna::Millisecond now = anna::functions::millisecond ();
172 const int delay = now - (Millisecond) response.initTime;
174 if (delay > 0 && isOk (response) == true) {
175 a_rxMessageCounter ++;
176 a_avgResponseTime += delay;
179 string msg = anna::functions::asString (
180 "%d %c %d = %d", response.x, response.op, response.y, response.result
182 msg += anna::functions::asText (" | Delay: ", delay);
183 Logger::information (msg, ANNA_FILE_LOCATION);
188 string msg = anna::functions::asString (
189 "Flip: %d %c %d = %d", response.x, response.op, response.y, response.result
191 msg += anna::functions::asText (" | Message: ", message.getBody ());
192 msg += anna::functions::asText (" | Delay: ", delay);
193 Logger::warning (msg, ANNA_FILE_LOCATION);
198 void MyCommunicator::eventBreakConnection (const ClientSocket& clientSocket)
201 if (a_rxMessageCounter == 0)
205 HeavyClient& app = static_cast <HeavyClient&> (anna::app::functions::getApp ());
206 string msg ("Tiempo medio respuesta: ");
207 msg += anna::functions::asString (a_avgResponseTime / a_rxMessageCounter);
209 msg += anna::functions::asText (" | Rx: ", a_rxMessageCounter);
210 msg += anna::functions::asText (" | Tx: ", app.getSender ()->getTxMessageCounter ());
211 Logger::notice (msg, ANNA_FILE_LOCATION);
213 cout << msg << endl << endl;
216 comm::Communicator::eventBreakConnection (clientSocket);
219 bool MyCommunicator::isOk (const test::Response& response)
222 if (response.op != '+' && response.op != '-' && response.op != '*' && response.op != '/')
227 switch (response.op) {
229 result = response.x + response.y;
232 result = response.x - response.y;
235 result = response.x * response.y;
238 result = (response.y != 0) ? (response.x / response.y): 0;
242 return result == response.result;
246 throw (RuntimeException)
248 Server* server = static_cast <HeavyClient&> (anna::app::functions::getApp ()).getServer ();
249 Communicator* communicator = anna::app::functions::component <Communicator> (ANNA_FILE_LOCATION);
251 if (a_errorCounter > 10) {
252 Logger::warning ("Terminado por errores continuos en la conexion", ANNA_FILE_LOCATION);
254 communicator->requestStop ();
256 catch (RuntimeException& ex) {
262 test::Request& request = a_requests.get ();
264 for (int n = 0; n < a_messageBySecond && communicator->hasRequestedStop () == false; n ++) {
266 request.x = rand () % 1000;
267 request.y = rand () % 1000;
268 request.initTime = anna::functions::millisecond ();
271 server->send (request);
272 a_txMessageCounter ++;
274 catch (RuntimeException& ex) {
275 string msg (ex.getText ());
276 msg += anna::functions::asText (" | ErrorCounter: ", ++ a_errorCounter);
277 Logger::warning (msg, ANNA_FILE_LOCATION);