libmoldeo (Moldeo 1.0 Core)  1.0
libmoldeo is the group of objects and functions that executes the basic operations of Moldeo 1.0 Platform.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
moNetManager.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2 
3  moNetManager.cpp
4 
5  ****************************************************************************
6  * *
7  * This source is free software; you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation; either version 2 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This code is distributed in the hope that it will be useful, but *
13  * WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
15  * General Public License for more details. *
16  * *
17  * A copy of the GNU General Public License is available on the World *
18  * Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
19  * obtain it by writing to the Free Software Foundation, *
20  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21  * *
22  ****************************************************************************
23 
24  Copyright(C) 2006 Fabricio Costa
25 
26  Authors:
27  Fabricio Costa
28 
29 
30 ******************************************************************************/
31 
32 #include "moNetManager.h"
33 
34 #include "moArray.h"
35 moDefineDynamicArray(moNetObjects)
36 moDefineDynamicArray( moNetConnections )
37 
38 #include <boost/bind.hpp>
39 
40 #ifndef MO_MACOSX
41 #include <boost/asio.hpp>
42 #else
43 #include <boost/asio.hpp>
44 #endif
45 
46 #include <boost/shared_ptr.hpp>
47 
48 #ifdef MO_WIN32
49  using namespace boost;
50  using namespace boost::asio;
51  using namespace boost::asio::ip;
52 #endif
53 
54 #ifdef MO_MACOSX
55  using namespace boost;
56  using namespace asio;
57  using namespace asio::ip;
58 #endif
59 
60 #ifdef MO_LINUX
61  using namespace boost;
62  using namespace asio;
63  using namespace asio::ip;
64 #endif
65 
66 
67 class moBoostHandleFunctions {
68 
69  public:
70 
71  moBoostHandleFunctions( void* pObject, moNetObjectType p_type ) {
72  m_pObject = pObject;
73  m_type = p_type;
74  }
75  virtual ~moBoostHandleFunctions() {
76 
77  }
78 
79  public:
80 
81 #ifdef MO_WIN32
82  void HandleRead( const system::error_code& e,
83  std::size_t bytes_transferred ) {
84 
85  moNetConnection* pConnection;
86 
87  if (!e) {
88  switch(m_type) {
89  case MO_NET_CONNECTION:
90  pConnection = (moNetConnection*) m_pObject;
91  pConnection->HandleRead( (long)bytes_transferred );
92  break;
93  case MO_NET_SESSION:
94  //m_pObject->HandleAccept();
95  break;
96  case MO_NET_SERVER:
97  //moNetServer* pServer = (moNetServer*) m_pObject;
98 
99  //pServer->HandleRead();
100  break;
101  }
102  }
103  }
104 
106  void HandleWrite(const boost::system::error_code& e) {
107 
108  moNetConnection* pConnection;
109 
110  if (!e) {
111  switch(m_type) {
112  case MO_NET_CONNECTION:
113  pConnection = (moNetConnection*) m_pObject;
114  pConnection->HandleWrite();
115  break;
116  case MO_NET_SESSION:
117  //m_pObject->HandleAccept();
118  break;
119  case MO_NET_SERVER:
120  //moNetServer* pServer = (moNetServer*) m_pObject;
121 
122  //pServer->HandleRead();
123  break;
124  }
125  }
126  }
127 
128 
129  void HandleAccept( const boost::system::error_code& e ) {
130  if (!e) {
131  switch(m_type) {
132  case MO_NET_CONNECTION:
133  //m_pObject->HandleAccept();
134  break;
135  case MO_NET_SESSION:
136  //m_pObject->HandleAccept();
137  break;
138  case MO_NET_SERVER:
139  moNetServer* pServer = (moNetServer*) m_pObject;
140 
141  pServer->HandleAccept();
142  break;
143  }
144  }
145  }
146 #endif
147  private:
148 
149  moNetObjectType m_type;
150  void* m_pObject;
151 
152 };
153 
154 
155 //===========================================
156 //
157 // moNetManager
158 //
159 //===========================================
160 
162 
163 }
164 
166 
167 }
168 
169 //===========================================
170 //
171 // moNetConnection
172 //
173 //===========================================
174 
176 
177  m_Socket = NULL;
178  m_Resolver = NULL;
179 
180  asio::io_service *p_io_service = (asio::io_service *) pIOS;
181 
182  tcp::socket* p_socket = new tcp::socket( (*p_io_service) );
183 
184  if (p_socket)
185  m_Socket = (void*)p_socket;
186 
187  tcp::resolver *p_resolver = new tcp::resolver( (*p_io_service) );
188 
189  if (p_resolver)
190  m_Resolver = (void*)p_resolver;
191 
192 /*
193  tcp::resolver::query query( , "http");
194  tcp::resolver::iterator endpoint_iterator = m_Resolver->resolve( query );
195  tcp::resolver::iterator end;
196 
197 
198 
199  tcp::no_delay option( true );
200  p_socket->set_option( option );
201  p_socket->connect(*endpoint_iterator++, error);
202 
203 */
204 }
205 
207 
208 }
209 
211 
212  if (m_Socket) {
213  //tcp::socket* p_socket = (tcp::socket*) m_Socket;
214 
215  /*p_socket->async_read_some( boost::asio::buffer(buffer_),
216  boost::bind(&connection::handle_read, shared_from_this(),
217  boost::asio::placeholders::error,
218  boost::asio::placeholders::bytes_transferred));
219  */
220  }
221 
222  // Try each endpoint until we successfully establish a connection.
223 /*
224  boost::system::error_code error = boost::asio::error::host_not_found;
225  while (error && endpoint_iterator != end)
226  {
227  socket.close();
228  socket.connect(*endpoint_iterator++, error);
229  }
230  if (error)
231  throw boost::system::system_error(error);
232 */
233  // Form the request. We specify the "Connection: close" header so that the
234  // server will close the socket after transmitting the response. This will
235  // allow us to treat all data up until the EOF as the content.
236  /*
237  boost::asio::streambuf request;
238  std::ostream request_stream(&request);
239  request_stream << "GET " << argv[2] << " HTTP/1.0\r\n";
240  request_stream << "Host: " << argv[1] << "\r\n";
241  */
242  //request_stream << "Accept: */*\r\n";
243  //request_stream << "Connection: close\r\n\r\n";
244 
245  // Send the request.
246  //boost::asio::write(socket, request);
247 
248  return false;
249 }
250 
251 
252 
254 
255  if (m_Socket) {
256 
257  tcp::socket* p_socket = (tcp::socket*) m_Socket;
258 
259  p_socket->close();
260 
261  }
262 
263  return true;
264 }
265 
267 
268  return m_Socket;
269 
270 }
271 
272 
273 void
274 moNetConnection::HandleRead( long bytesbuf ) {
275 
276  bytesbuf = 0 + bytesbuf;
277 /*
278  boost::tribool result;
279 
280  boost::tie(result, boost::tuples::ignore) = request_parser_.parse(
281  request_, buffer_.data(), buffer_.data() + bytes_transferred);
282 
283  if (result)
284  {
285  request_handler_.handle_request(request_, reply_);
286 
287  boost::asio::async_write(socket_, reply_.to_buffers(),
288  boost::bind(&connection::handle_write, shared_from_this(),
289  boost::asio::placeholders::error));
290  }
291  else if (!result)
292  {
293  reply_ = reply::stock_reply(reply::bad_request);
294 
295  boost::asio::async_write( socket_, reply_.to_buffers(),
296  boost::bind(&connection::handle_write, shared_from_this(),
297  boost::asio::placeholders::error));
298  }
299  else
300  {
301  socket_.async_read_some( boost::asio::buffer(buffer_),
302  boost::bind(&connection::handle_read, shared_from_this(),
303  boost::asio::placeholders::error,
304  boost::asio::placeholders::bytes_transferred));
305  }
306 */
307 }
308 
309 void
311  // Initiate graceful connection closure.
312  /*
313  boost::system::error_code ignored_ec;
314 
315  if (m_Socket) {
316 
317  tcp::socket* p_socket = (tcp::socket*) m_Socket;
318 
319  p_socket->shutdown( boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
320 
321  }
322  */
323 
324 }
325 
326 //===========================================
327 //
328 // moNetConnectionManager
329 //
330 //===========================================
331 
332 
334 
335 
336 }
337 
339 
340 }
341 
342 
344  m_Connections.Add( p_new_connection );
345  p_new_connection->Start();
346 }
347 
349  for( int i=0; i<(int)m_Connections.Count(); i++) {
350  if (m_Connections[i]==p_connection) {
351  m_Connections.Remove(i);
352  p_connection->Stop();
353  i--;
354  }
355 
356  }
357 }
358 
360  for( int i=0; i<(int)m_Connections.Count(); i++) {
361  if (m_Connections[i]) {
362  m_Connections[i]->Stop();
363  }
364 
365  }
366  m_Connections.Empty();
367 }
368 
369 //===========================================
370 //
371 // moNetServer
372 //
373 //===========================================
374 
376 {
377 
378  m_ConnectionManager.Start( m_pNewConnection );
379 
380  m_pNewConnection = new moNetConnection( m_pIOService );
381 
382  tcp::acceptor *p_acceptor = (tcp::acceptor *) m_pAcceptor;
383  if (p_acceptor) {
384 
385  //tcp::socket* p_socket = (tcp::socket*) m_pNewConnection->Socket();
386 
387  //moBoostHandleFunctions* pFunctions = (moBoostHandleFunctions*) m_pHandleFunctions;
388 
389  /*
390  p_acceptor->async_accept( *p_socket,
391  boost::bind( &moBoostHandleFunctions::HandleAccept, pFunctions,
392  placeholders::error));
393  */
394  }
395 
396 }
397 
398 /*
399 
400 void HandleAccept( const boost::system::error_code& error )
401 {
402  if (!error) {
404  }
405 }
406 
407 
408 */
409 moNetServer::moNetServer( moAddress p_address, moPort p_port, moText p_directory ) {
410 
411  m_pIOService = NULL;
412 
413  if ( p_directory==moText("") ) p_directory = "";
414 
415  io_service* p_io_service = new io_service();
416  m_pIOService = (void*) p_io_service;
417 
418  if (m_pIOService) {
419 
420  m_pNewConnection = new moNetConnection( m_pIOService );
421 
422 
423  // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
424  tcp::resolver resolver( *p_io_service );
425 
426  tcp::resolver::query query( (char*)p_address, (char*)p_port);
427 
428  tcp::endpoint endpoint = *resolver.resolve(query);
429 
430  tcp::acceptor *p_acceptor = new tcp::acceptor( *p_io_service );
431  m_pAcceptor = (void*) p_acceptor;
432 
433  if (m_pAcceptor) {
434  p_acceptor->open( endpoint.protocol() );
435  p_acceptor->set_option( tcp::acceptor::reuse_address(true) );
436  p_acceptor->bind( endpoint );
437  p_acceptor->listen();
438 
440 
441  /*
442  p_acceptor->async_accept( *p_socket,
443  boost::bind( &moNetServer::HandleAccept, this,
444  boost::asio::placeholders::error));
445 
446  */
447  moBoostHandleFunctions* pFunctions = new moBoostHandleFunctions( (void*) this, MO_NET_SERVER );
448  m_pHandleFunctions = (void*) pFunctions;
449  /*
450  p_acceptor->async_accept( *p_socket,
451  boost::bind( &moBoostHandleFunctions::HandleAccept, pFunctions,
452  placeholders::error ));
453  */
454 
455 
456  }
457  }
458 }
459 
460 
462 
463 }
464 
465 
466 void
468  io_service* p_io_service = NULL;
469  if (m_pIOService) {
470  p_io_service = (io_service*) m_pIOService;
471 
472 
473  p_io_service->run();
474  }
475 }
476 
477 void
479  io_service* p_io_service = NULL;
480  if (m_pIOService) {
481  p_io_service = (io_service*) m_pIOService;
482 
483  p_io_service->post( boost::bind( &moNetServer::HandleStop, this) );
484  }
485 
486 }
487 
488 
489 
490 
491 void
492 moNetServer::HandleStop() {
493 
494  // The server is stopped by cancelling all outstanding asynchronous
495  // operations. Once all operations have finished the io_service::run() call
496  // will exit.
497  tcp::acceptor* p_acceptor = NULL;
498  p_acceptor = (tcp::acceptor*) m_pAcceptor;
499  if (p_acceptor) {
500  p_acceptor->close();
501  }
502  m_ConnectionManager.StopAll();
503 
504 }
505 
506 
507 //===========================================
508 //
509 // moNetManager
510 //
511 //===========================================
512 
514  SetType( MO_OBJECT_RESOURCE );
515  SetResourceType( MO_RESOURCETYPE_NET );
516 
517  SetName("netmanager");
518  SetLabelName("netmanager");
519 }
520 
522 
523 }
524 
526  m_NetObjects.Init(0,NULL);
527 
528 
529 
530  return true;
531 }
532 
533 
535  m_NetObjects.Finish();
536  return true;
537 }
538 
539 
moDefineDynamicArray(moNetObjects) moDefineDynamicArray(moNetConnections) class moBoostHandleFunctions
moNetServer(moAddress p_address, moPort p_port, moText p_directory)
void Start(moNetConnection *p_new_connection)
void HandleAccept()
virtual ~moNetConnectionManager()
virtual MOboolean Finish()
#define MOboolean
Definition: moTypes.h:385
moNetObjectType
Definition: moNetManager.h:63
void HandleRead(long bytesbuf)
virtual ~moNetServer()
clase de para manejar textos
Definition: moText.h:75
Dispositivo de entrada/salida, típicamente, interfaces humanas de IO y datos ( teclado, mouse, tableta, tcp, udp, serial )
Definition: moTypes.h:532
moText0 moText
Definition: moText.h:291
virtual ~moNetObject()
void HandleWrite()
Handle completion of a write operation.
void * moBoostSocket
Definition: moNetManager.h:52
moBoostSocket Socket()
void * moBoostIOService
Boost.Asio specific classes type definitions.
Definition: moNetManager.h:47
moNetConnection(moBoostIOService pIOS)
clase para crear y mantener una conección basada en el protocolo tcp
Definition: moNetManager.h:85
virtual MOboolean Init()
void Stop(moNetConnection *p_connection)
virtual ~moNetManager()
virtual ~moNetConnection()