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 <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
00028
00029
00030 namespace ecl {
00031
00032
00033
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
00055
00056
00057
00058
00059
00060 socket_fd = socket(AF_INET, SOCK_STREAM, 0);
00061
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
00070
00071 struct sockaddr_in server;
00072 server.sin_family = AF_INET;
00073 server.sin_addr.s_addr = INADDR_ANY;
00074 server.sin_port = htons(port);
00075 memset(server.sin_zero, '\0', sizeof server.sin_zero);
00076
00077
00078
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
00096
00097 ::listen(socket_fd,1);
00098
00099
00100
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
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
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
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 }
00193
00194 #endif
00195 #endif