Go to the documentation of this file.00001
00009
00010
00011
00012
00013 #include <ecl/config/ecl.hpp>
00014 #ifndef ECL_IS_MAC
00015 #ifdef ECL_IS_POSIX
00016
00017
00018
00019
00020
00021 #include <iostream>
00022 #include <netdb.h>
00023 #include <ecl/exceptions/standard_exception.hpp>
00024 #include "../../include/ecl/devices/detail/socket_error_handler_pos.hpp"
00025 #include "../../include/ecl/devices/detail/socket_exception_handler_pos.hpp"
00026 #include "../../include/ecl/devices/socket_connection_status.hpp"
00027 #include "../../include/ecl/devices/socket_client_pos.hpp"
00028
00029
00030
00031
00032
00033 namespace ecl {
00034
00035
00036
00037
00038
00039 using std::string;
00040
00041
00042
00043
00044
00045 SocketClient::SocketClient(const std::string &host_name, const unsigned int &port_number) ecl_throw_decl(StandardException) :
00046 hostname(host_name),
00047 port(port_number),
00048 is_open(false),
00049 error_handler(NoError)
00050 {
00051 ecl_try {
00052 open(host_name, port_number);
00053 } ecl_catch ( StandardException &e ) {
00054 ecl_throw(StandardException(LOC,e));
00055 }
00056 }
00057
00058 void SocketClient::close() {
00059 is_open = false;
00060 ::close(socket_fd);
00061 }
00062
00063 bool SocketClient::open( const std::string &host_name, const unsigned int& port_number ) ecl_throw_decl(StandardException) {
00064
00065 if ( this->open() ) { this->close(); }
00066 hostname = host_name;
00067 port = port_number;
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 socket_fd = socket(AF_INET, SOCK_STREAM, 0);
00078
00079 if ( socket_fd == -1 ) {
00080 ecl_throw(devices::socket_exception(LOC));
00081 error_handler = devices::socket_error();
00082 return false;
00083 }
00084
00085
00086
00087 struct hostent *host_entry;
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 host_entry = gethostbyname(hostname.c_str());
00098 if ( host_entry == NULL ) {
00099 ::close(socket_fd);
00100 ecl_throw(devices::gethostbyname_exception(LOC,hostname));
00101 error_handler = devices::gethostbyname_error();
00102 return false;
00103 }
00104
00105
00106
00107
00108 struct sockaddr_in destination;
00109 destination.sin_family = AF_INET;
00110 destination.sin_addr = *((struct in_addr *)host_entry->h_addr);
00111 destination.sin_port = htons(port);
00112 memset(destination.sin_zero, '\0', sizeof destination.sin_zero);
00113
00114
00115
00116
00117 int connect_result = connect( socket_fd, (struct sockaddr *) &destination, sizeof(destination) );
00118 if ( connect_result == -1 ) {
00119 is_open = false;
00120 ::close(socket_fd);
00121 ecl_throw(devices::connection_exception(LOC));
00122 error_handler = devices::connection_error();
00123 return false;
00124 }
00125 is_open = true;
00126 error_handler = NoError;
00127 return true;
00128 }
00129
00130
00131
00132
00133
00134 long SocketClient::read(char &c) ecl_assert_throw_decl(StandardException) {
00135 return read(&c,1);
00136 }
00137
00138 long SocketClient::read(char *s, const unsigned long &n) ecl_assert_throw_decl(StandardException) {
00139
00140 if ( !open() ) {
00141 return ConnectionDisconnected;
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151 int bytes_read = ::recv(socket_fd, s, n, 0);
00152
00153
00154
00155
00156 if ( bytes_read == 0 ) {
00157
00158 close();
00159 return ConnectionHungUp;
00160 }
00161 if ( bytes_read < 0 ) {
00162 if ( errno == ECONNRESET ) {
00163 close();
00164 return ConnectionHungUp;
00165 } else {
00166 ecl_debug_throw( devices::receive_exception(LOC) );
00167 error_handler = devices::receive_error();
00168 return ConnectionProblem;
00169 }
00170 }
00171 error_handler = NoError;
00172 return bytes_read;
00173 }
00174
00175 long SocketClient::peek(char *s, const unsigned long &n) ecl_assert_throw_decl(StandardException) {
00176
00177 if ( !open() ) { return ConnectionDisconnected; }
00178
00179 int bytes_read = ::recv(socket_fd, s, n, MSG_PEEK);
00180 if ( bytes_read < 0 ) {
00181 ecl_debug_throw( devices::receive_exception(LOC) );
00182 error_handler = devices::receive_error();
00183 return ConnectionProblem;
00184 }
00185 error_handler = NoError;
00186 return bytes_read;
00187 };
00188
00189 long SocketClient::remaining() {
00190
00191 if ( !open() ) { return ConnectionDisconnected; }
00192
00193 unsigned long bytes;
00194 int result = ioctl(socket_fd, FIONREAD, &bytes);
00195 if ( result == -1 ) {
00196 ecl_debug_throw( devices::ioctl_exception(LOC) );
00197 error_handler = devices::ioctl_error();
00198 }
00199 error_handler = NoError;
00200 return bytes;
00201 };
00202
00203
00204
00205
00206
00207 long SocketClient::write(const char &c) ecl_assert_throw_decl(StandardException) {
00208
00209 return write(&c, 1);
00210 }
00211
00212 long SocketClient::write(const char *s, unsigned long n) ecl_assert_throw_decl(StandardException) {
00213
00214 if ( !open() ) { return ConnectionDisconnected; }
00215
00216
00217
00218
00219 int bytes_written = ::send(socket_fd,s,n,MSG_NOSIGNAL);
00220
00221 if ( bytes_written < 0 ) {
00222 switch(errno) {
00223 case ( EPIPE ) : {
00224 close();
00225 return ConnectionHungUp;
00226 }
00227 default : {
00228 ecl_debug_throw( devices::send_exception(LOC) );
00229 error_handler = devices::send_error();
00230 return ConnectionProblem;
00231 }
00232 }
00233 }
00234 return bytes_written;
00235 }
00236
00237 }
00238
00239 #endif
00240 #endif