socket_server_pos.cpp
Go to the documentation of this file.
00001 
00009 /*****************************************************************************
00010 ** Cross platform
00011 *****************************************************************************/
00012 
00013 #include <ecl/config/ecl.hpp>
00014 #ifndef ECL_IS_APPLE
00015 #ifdef ECL_IS_POSIX
00016 
00017 /*****************************************************************************
00018 ** Includes
00019 *****************************************************************************/
00020 
00021 #include <unistd.h>
00022 #include <ecl/exceptions/standard_exception.hpp>
00023 #include "../../include/ecl/devices/socket_connection_status.hpp"
00024 #include "../../include/ecl/devices/socket_server_pos.hpp"
00025 
00026 /*****************************************************************************
00027 ** Namespaces
00028 *****************************************************************************/
00029 
00030 namespace ecl {
00031 
00032 /*****************************************************************************
00033 ** Implementation [SocketServer]
00034 *****************************************************************************/
00035 
00036 SocketServer::SocketServer(const unsigned int &port_number) ecl_throw_decl(StandardException) :
00037                 port(port_number),
00038                 is_open(false),
00039                 error_handler(NoError)
00040 {
00041     ecl_try {
00042         open(port_number);
00043     } ecl_catch ( const StandardException &e ) {
00044         ecl_throw(StandardException(LOC,e));
00045     }
00046 }
00047 
00048 bool SocketServer::open( const unsigned int& port_number ) ecl_throw_decl(StandardException) {
00049 
00050     if ( this->open() ) { this->close(); }
00051     port = port_number;
00052 
00053     /*************************************************************************
00054      * Open socket
00055      *************************************************************************
00056      * PF_INET (IP4), PF_LOCAL (LOCALHOST)
00057      * SOCK_STREAM (TCPIP), SOCK_DGRAM (UDP), SOCK_RAW
00058      * Last argument is generally always 0 (sub-type)
00059      */
00060     socket_fd = socket(AF_INET, SOCK_STREAM, 0);
00061 //    socket_fd = socket(PF_INET, SOCK_STREAM, 0);
00062     if ( socket_fd == -1 ) {
00063         ecl_throw(devices::socket_exception(LOC));
00064         error_handler = devices::socket_error();
00065         return false;
00066     }
00067 
00068     /*************************************************************************
00069      * Configure Socket Details
00070      ************************************************************************/
00071     struct sockaddr_in server;
00072     server.sin_family = AF_INET;    // host byte order
00073     server.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
00074     server.sin_port = htons(port);  // short host byte order to network byte order
00075     memset(server.sin_zero, '\0', sizeof server.sin_zero); // zero the server structure
00076 
00077     /*************************************************************************
00078      * Bind address to the socket
00079      ************************************************************************/
00080     int bind_result = bind(socket_fd, (struct sockaddr *) &server, sizeof(server));
00081     if ( bind_result == - 1 ) {
00082         is_open = true;
00083         ecl_throw(devices::bind_exception(LOC));
00084         error_handler = devices::bind_error();
00085         return false;
00086     }
00087     is_open = true;
00088     error_handler = NoError;
00089     return true;
00090 }
00091 
00092 int SocketServer::listen() ecl_throw_decl(StandardException) {
00093 
00094         /*********************
00095         ** Params
00096         **********************/
00097         ::listen(socket_fd,1); // Number of clients to allow
00098 
00099         /*********************
00100         ** Listen
00101         **********************/
00102     struct sockaddr_in client;
00103     int client_length = sizeof(client);
00104 
00105     client_socket_fd = accept(socket_fd, (struct sockaddr *) &client, (socklen_t *) &client_length);
00106     if (client_socket_fd < 0) {
00107         ecl_throw(devices::accept_exception(LOC));
00108         error_handler =devices::accept_error();
00109         return -1;
00110     }
00111     error_handler = NoError;
00112     return client_socket_fd;
00113 
00114 }
00115 
00116 /*****************************************************************************
00117 ** Implementation [SocketServer][Source]
00118 *****************************************************************************/
00119 
00120 long SocketServer::read(char *s, const unsigned long &n) ecl_debug_throw_decl(StandardException) {
00121 
00122     if ( !open() ) { return ConnectionDisconnected; }
00123 
00124     int bytes_read = ::recv(client_socket_fd, s, n, 0);
00125     if ( bytes_read < 0 ) {
00126         ecl_debug_throw(devices::receive_exception(LOC));
00127         error_handler = devices::receive_error();
00128         return ConnectionProblem;
00129     }
00130 
00131     if ( bytes_read == 0 ) {
00132         // Server has dropped
00133         close();
00134         return ConnectionHungUp;
00135     }
00136     error_handler = NoError;
00137     return bytes_read;
00138 }
00139 
00140 long SocketServer::peek(char *s, const unsigned long &n) ecl_debug_throw_decl(StandardException) {
00141 
00142         int bytes_read = ::recv(client_socket_fd, s, n, MSG_PEEK);
00143     if ( bytes_read < 0 ) {
00144         ecl_debug_throw(devices::receive_exception(LOC));
00145         error_handler = devices::receive_error();
00146         return ConnectionProblem;
00147     }
00148     error_handler = NoError;
00149     return bytes_read;
00150 };
00151 
00152 long SocketServer::remaining() {
00153     unsigned long bytes;
00154     int result = ioctl(client_socket_fd, FIONREAD, &bytes);
00155     if ( result == -1 ) {
00156         ecl_debug_throw(devices::ioctl_exception(LOC));
00157         error_handler = devices::ioctl_error();
00158         return ConnectionProblem;
00159     }
00160     error_handler = NoError;
00161     return bytes;
00162 };
00163 
00164 
00165 /*****************************************************************************
00166 ** Implementation [SocketServer][Sink]
00167 *****************************************************************************/
00168 
00169 long SocketServer::write(const char *s, unsigned long n) ecl_debug_throw_decl(StandardException) {
00170     #ifdef MSG_NOSIGNAL
00171         int bytes_written = ::send(client_socket_fd,s,n,0|MSG_NOSIGNAL);
00172     #else
00173         int bytes_written = ::send(client_socket_fd,s,n,0);
00174     #endif
00175     if ( bytes_written < 0 ) {
00176         switch(errno) {
00177             case ( EPIPE ) : {
00178                 close();
00179                 return ConnectionHungUp;
00180             }
00181             default : {
00182                     ecl_debug_throw( devices::send_exception(LOC) );
00183                     error_handler = devices::send_error();
00184                     return ConnectionProblem;
00185             }
00186         }
00187     }
00188     error_handler = NoError;
00189     return bytes_written;
00190 }
00191 
00192 } // namespace ecl
00193 
00194 #endif /* ECL_IS_POSIX */
00195 #endif  /* !ECL_IS_APPLE */


ecl_devices
Author(s): Daniel Stonier
autogenerated on Wed Aug 26 2015 11:27:37