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