[Positioning] Add class OutputNetworkSocket

Factorise code of OutputUDPSocket and OutputTCPSocketEvAAL.
This commit is contained in:
Matteo Cypriani 2011-07-30 15:58:48 +02:00
parent 21c7f80345
commit cd25c4ddcd
8 changed files with 151 additions and 133 deletions

View File

@ -101,6 +101,7 @@ OBJ_NOTEST_LIST = \
posexcept.o \ posexcept.o \
multilaterationalgorithm.o \ multilaterationalgorithm.o \
cartographyalgorithm.o \ cartographyalgorithm.o \
outputnetworksocket.o \
inputmedium.o inputmedium.o
INTERFACES_LIST = \ INTERFACES_LIST = \
inputlogmedium.hh \ inputlogmedium.hh \
@ -246,12 +247,24 @@ $(OBJ_DIR)/outputcsv.o: \
$(OBJ_DIR)/textfilewriter.o \ $(OBJ_DIR)/textfilewriter.o \
$(OBJ_DIR)/resultlist.o \ $(OBJ_DIR)/resultlist.o \
$(OBJ_DIR)/result.o $(OBJ_DIR)/result.o
$(OBJ_DIR)/outputnetworksocket.o: \
$(SRC_DIR)/outputmedium.hh \
$(OBJ_DIR)/resultlist.o \
$(OBJ_DIR)/result.o
$(OBJ_DIR)/outputudpsocket.o: \ $(OBJ_DIR)/outputudpsocket.o: \
$(SRC_DIR)/outputmedium.hh \ $(OBJ_DIR)/outputnetworksocket.o \
$(OBJ_DIR)/result.o $(OBJ_DIR)/request.o \
$(OBJ_DIR)/resultlist.o \
$(OBJ_DIR)/result.o \
$(OBJ_DIR)/posexcept.o
$(OBJ_DIR)/outputtcpsocketevaal.o: \ $(OBJ_DIR)/outputtcpsocketevaal.o: \
$(SRC_DIR)/outputmedium.hh \ $(OBJ_DIR)/outputnetworksocket.o \
$(OBJ_DIR)/result.o $(OBJ_DIR)/request.o \
$(OBJ_DIR)/resultlist.o \
$(OBJ_DIR)/result.o \
$(OBJ_DIR)/area.o \
$(OBJ_DIR)/posexcept.o \
$(OBJ_DIR)/stock.o
$(OBJ_DIR)/outputcsv.o: \ $(OBJ_DIR)/outputcsv.o: \
$(SRC_DIR)/outputmedium.hh \ $(SRC_DIR)/outputmedium.hh \
$(OBJ_DIR)/result.o $(OBJ_DIR)/result.o

View File

@ -18,8 +18,6 @@
- Refactoring - Refactoring
° Split Stock::regenerate_reference_points() into several ° Split Stock::regenerate_reference_points() into several
functions. functions.
° Create virtual class OutputSocket to factorise code of
OutputUDPSocket & OutputTCPSocketEvAAL.
° Synchronise InputCSV & InputUDPSocket (calibration requests), ° Synchronise InputCSV & InputUDPSocket (calibration requests),
factorise code into InputMedium. factorise code into InputMedium.
° Write a class for Request::type? ° Write a class for Request::type?

View File

@ -0,0 +1,60 @@
#include "outputnetworksocket.hh"
#include "resultlist.hh"
#include "result.hh"
#include "posexcept.hh"
#include <cstdio> // For perror()
using namespace std ;
/* *** Constructors *** */
OutputNetworkSocket::~OutputNetworkSocket()
{
close_socket() ;
}
/* *** Operations *** */
/**
* Normally, the socket is closed automatically by the destructor. Use
* this if you want to close the socket prematurely.
* #sockfd is set to -1, even in case of error.
* @return \em true if the socket were successfully closed or were not
* opened.
* @return \em false in case of error.
*/
bool OutputNetworkSocket::close_socket()
{
if (sockfd >= 0)
{
if (close(sockfd))
{
perror("Cannot close network socket") ;
return false ;
}
sockfd = -1 ;
}
return true ;
}
void OutputNetworkSocket::write(const Result &result)
{
send_data(result.to_csv()) ;
}
void OutputNetworkSocket::write(const ResultList &results)
{
if (! results.empty())
send_data(results.to_csv()) ;
}

View File

@ -0,0 +1,50 @@
#ifndef _OWLPS_POSITIONING_OUTPUTNETWORKSOCKET_HH_
#define _OWLPS_POSITIONING_OUTPUTNETWORKSOCKET_HH_
#include "outputmedium.hh"
#include <string>
#include <stdint.h> // <cstdint> is not C++ 98 compliant
#include <arpa/inet.h>
/// Parent class for all output media that use network sockets
class OutputNetworkSocket: public OutputMedium
{
protected:
int sockfd ;
std::string remote_host ;
uint_fast16_t remote_port ;
struct sockaddr_in server_info ;
struct sockaddr_in client_info ;
/** @name Operations */
//@{
/// Initialises the socket
/**
* You are required to call this function from the constructor of any
* derived class.
*/
virtual bool init_socket(void) = 0 ;
/// Sends a string through the socket
virtual bool send_data(const std::string &data) const = 0 ;
//@}
public:
OutputNetworkSocket(const std::string &_remote_host,
const uint_fast16_t _remote_port):
sockfd(-1), remote_host(_remote_host), remote_port(_remote_port) {}
~OutputNetworkSocket(void) ;
/** @name Operations */
//@{
/// Sends a list of results through the socket
void write(const ResultList &results) ;
/// Sends a single result through the socket
void write(const Result &result) ;
/// Closes the socket
bool close_socket(void) ;
//@}
} ;
#endif // _OWLPS_POSITIONING_OUTPUTNETWORKSOCKET_HH_

View File

@ -17,19 +17,13 @@ using namespace std ;
/* *** Constructors *** */ /* *** Constructors *** */
OutputTCPSocketEvAAL::OutputTCPSocketEvAAL( OutputTCPSocketEvAAL::
const string &_remote_host, OutputTCPSocketEvAAL(const string &_remote_host,
const uint_fast16_t _remote_port): const uint_fast16_t _remote_port):
remote_host(_remote_host), remote_port(_remote_port) OutputNetworkSocket(_remote_host, _remote_port)
{ {
if (! init_socket()) if (! init_socket())
throw error_opening_output_file("TCP socket") ; throw error_opening_output_file("TCP socket (EvAAL)") ;
}
OutputTCPSocketEvAAL::~OutputTCPSocketEvAAL()
{
close_socket() ;
} }
@ -70,31 +64,6 @@ bool OutputTCPSocketEvAAL::init_socket()
} }
/**
* Normally, the socket is closed automatically by the destructor. Use
* this if you want to close the socket prematurely.
* #sockfd is set to -1, even in case of error.
* @return \em true if the socket were successfully closed or were not
* opened.
* @return \em false in case of error.
*/
bool OutputTCPSocketEvAAL::close_socket()
{
if (sockfd >= 0)
{
if (close(sockfd))
{
perror("Cannot close TCP socket") ;
return false ;
}
sockfd = -1 ;
}
return true ;
}
/** /**
* @param results Must contain only one element, since the EvAAL format * @param results Must contain only one element, since the EvAAL format
* accepts only one algorithm result. * accepts only one algorithm result.
@ -157,7 +126,7 @@ bool OutputTCPSocketEvAAL::send_data(const string &data) const
ssize_t nsent = send(sockfd, data.c_str(), data.size(), 0) ; ssize_t nsent = send(sockfd, data.c_str(), data.size(), 0) ;
if (nsent != static_cast<ssize_t>(data.size())) if (nsent != static_cast<ssize_t>(data.size()))
{ {
perror("Error sending result data") ; perror("Error sending result data through the TCPEvAAL socket") ;
return false ; return false ;
} }
return true ; return true ;

View File

@ -3,27 +3,16 @@
class Point3D ; class Point3D ;
#include "outputmedium.hh" #include "outputnetworksocket.hh"
#include <string>
#include <stdint.h> // <cstdint> is not C++ 98 compliant
#include <arpa/inet.h>
/// Sends results to a remote host by TCP (EvAAL competition format) /// Sends results to a remote host by TCP (EvAAL competition format)
/** /**
* The results are sent through an TCP socket as a string value, * The results are sent through an TCP socket as a string value,
* conforming to the EvAAL competition format. * conforming to the EvAAL competition format.
*/ */
class OutputTCPSocketEvAAL: public OutputMedium class OutputTCPSocketEvAAL: public OutputNetworkSocket
{ {
protected: protected:
int sockfd ;
std::string remote_host ;
uint_fast16_t remote_port ;
struct sockaddr_in server_info ;
struct sockaddr_in client_info ;
/** @name Operations */ /** @name Operations */
//@{ //@{
/// Initialises the socket /// Initialises the socket
@ -37,16 +26,15 @@ protected:
public: public:
OutputTCPSocketEvAAL(const std::string &_remote_host, OutputTCPSocketEvAAL(const std::string &_remote_host,
const uint_fast16_t _remote_port) ; const uint_fast16_t _remote_port) ;
~OutputTCPSocketEvAAL(void) ;
/** @name Operations */ /** @name Operations */
//@{ //@{
/// Sends a list of results through the socket
void write(const ResultList &results) ; void write(const ResultList &results) ;
/// Sends a single result through the socket
void write(const Result &result) ; void write(const Result &result) ;
/// Get the area of interest number from the position /// Get the area of interest number from the position
int area_of_interest_number(const Point3D &position) const ; int area_of_interest_number(const Point3D &position) const ;
/// Closes the socket
bool close_socket(void) ;
//@} //@}
} ; } ;

View File

@ -1,11 +1,11 @@
#include "outputudpsocket.hh" #include "outputudpsocket.hh"
#include "request.hh" #include "request.hh"
#include "resultlist.hh" #include "resultlist.hh"
#include "result.hh"
#include "posexcept.hh" #include "posexcept.hh"
#include <owlps.h> #include <owlps.h>
#include <sstream>
#include <cstdio> // For perror() #include <cstdio> // For perror()
using namespace std ; using namespace std ;
@ -17,17 +17,10 @@ using namespace std ;
OutputUDPSocket::OutputUDPSocket(const string &_remote_host, OutputUDPSocket::OutputUDPSocket(const string &_remote_host,
const uint_fast16_t _remote_port): const uint_fast16_t _remote_port):
remote_host(_remote_host), remote_port(_remote_port) OutputNetworkSocket(_remote_host, _remote_port)
{ {
if (! init_socket()) if (! init_socket())
throw error_opening_output_file("UDP socket") ; throw error_opening_output_file("UDP socket") ;
}
OutputUDPSocket::~OutputUDPSocket()
{
close_socket() ;
} }
@ -47,52 +40,18 @@ bool OutputUDPSocket::init_socket()
} }
/**
* Normally, the socket is closed automatically by the destructor. Use
* this if you want to close the socket prematurely.
* #sockfd is set to -1, even in case of error.
* @return \em true if the socket were successfully closed or were not
* opened.
* @return \em false in case of error.
*/
bool OutputUDPSocket::close_socket()
{
if (sockfd >= 0)
{
if (close(sockfd))
{
perror("Cannot close UDP socket") ;
return false ;
}
sockfd = -1 ;
}
return true ;
}
void OutputUDPSocket::write(const Result &result)
{
send_data(result.to_csv()) ;
}
void OutputUDPSocket::write(const ResultList &results)
{
if (! results.empty())
send_data(results.to_csv()) ;
}
/** /**
* Sends the text buffer 'data'. * Sends the text buffer 'data'.
*/ */
void OutputUDPSocket::send_data(const string &data) bool OutputUDPSocket::send_data(const string &data) const
{ {
ssize_t nsent = sendto(sockfd, data.c_str(), data.size(), 0, ssize_t nsent = sendto(sockfd, data.c_str(), data.size(), 0,
(struct sockaddr *) &server_info, (struct sockaddr *) &server_info,
sizeof(server_info)) ; sizeof(server_info)) ;
if (nsent != static_cast<ssize_t>(data.size())) if (nsent != static_cast<ssize_t>(data.size()))
perror("Error sending result data") ; {
perror("Error sending result data through the UDP socket") ;
return false ;
}
return true ;
} }

View File

@ -1,46 +1,27 @@
#ifndef _OWLPS_POSITIONING_OUTPUTUDPSOCKET_HH_ #ifndef _OWLPS_POSITIONING_OUTPUTUDPSOCKET_HH_
#define _OWLPS_POSITIONING_OUTPUTUDPSOCKET_HH_ #define _OWLPS_POSITIONING_OUTPUTUDPSOCKET_HH_
#include "outputmedium.hh" #include "outputnetworksocket.hh"
#include <string>
#include <stdint.h> // <cstdint> is not C++ 98 compliant
#include <arpa/inet.h>
/// Sends results to a remote host by UDP /// Sends results to a remote host by UDP
/** /**
* The results are sent through an UDP socket as a CSV string value. The * The results are sent through an UDP socket as a CSV string value. The
* format used is the same as in OutputCSV. * format used is the same as in OutputCSV.
*/ */
class OutputUDPSocket: public OutputMedium class OutputUDPSocket: public OutputNetworkSocket
{ {
protected: protected:
int sockfd ;
std::string remote_host ;
uint_fast16_t remote_port ;
struct sockaddr_in server_info ;
struct sockaddr_in client_info ;
/** @name Operations */ /** @name Operations */
//@{ //@{
/// Initialises the socket /// Initialises the socket
bool init_socket(void) ; bool init_socket(void) ;
void send_data(const std::string &data) ; /// Sends a string through the socket
bool send_data(const std::string &data) const ;
//@} //@}
public: public:
OutputUDPSocket(const std::string &_remote_ip, OutputUDPSocket(const std::string &_remote_host,
const uint_fast16_t _port) ; const uint_fast16_t _remote_port) ;
~OutputUDPSocket(void) ;
/** @name Operations */
//@{
void write(const Result &result) ;
void write(const ResultList &results) ;
/// Closes the socket
bool close_socket(void) ;
//@}
} ; } ;