$search
00001 00009 /***************************************************************************** 00010 ** Cross platform 00011 *****************************************************************************/ 00012 00013 #include <ecl/config/ecl.hpp> 00014 #ifndef ECL_IS_MAC 00015 #ifdef ECL_IS_POSIX 00016 00017 /***************************************************************************** 00018 ** Includes 00019 *****************************************************************************/ 00020 00021 #include <iostream> 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 int bytes_written = ::send(client_socket_fd,s,n,0); 00171 if ( bytes_written < 0 ) { 00172 switch(errno) { 00173 case ( EPIPE ) : { 00174 close(); 00175 return ConnectionHungUp; 00176 } 00177 default : { 00178 ecl_debug_throw( devices::send_exception(LOC) ); 00179 error_handler = devices::send_error(); 00180 return ConnectionProblem; 00181 } 00182 } 00183 } 00184 error_handler = NoError; 00185 return bytes_written; 00186 } 00187 00188 } // namespace ecl 00189 00190 #endif /* ECL_IS_POSIX */ 00191 #endif /* !ECL_IS_MAC */