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
00072 int ret, on;
00073 on = 1;
00074 ret = setsockopt( socket_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) );
00075
00076 struct sockaddr_in server;
00077 server.sin_family = AF_INET;
00078 server.sin_addr.s_addr = INADDR_ANY;
00079 server.sin_port = htons(port);
00080 memset(server.sin_zero, '\0', sizeof server.sin_zero);
00081
00082
00083
00084
00085 int bind_result = bind(socket_fd, (struct sockaddr *) &server, sizeof(server));
00086 if ( bind_result == - 1 ) {
00087 is_open = true;
00088 ecl_throw(devices::bind_exception(LOC));
00089 error_handler = devices::bind_error();
00090 return false;
00091 }
00092 is_open = true;
00093 error_handler = NoError;
00094 return true;
00095 }
00096
00097 int SocketServer::listen() ecl_throw_decl(StandardException) {
00098
00099
00100
00101
00102 ::listen(socket_fd,1);
00103
00104
00105
00106
00107 struct sockaddr_in client;
00108 int client_length = sizeof(client);
00109
00110 client_socket_fd = accept(socket_fd, (struct sockaddr *) &client, (socklen_t *) &client_length);
00111 if (client_socket_fd < 0) {
00112 ecl_throw(devices::accept_exception(LOC));
00113 error_handler =devices::accept_error();
00114 return -1;
00115 }
00116 error_handler = NoError;
00117 return client_socket_fd;
00118
00119 }
00120
00121
00122
00123
00124
00125 long SocketServer::read(char *s, const unsigned long &n) ecl_debug_throw_decl(StandardException) {
00126
00127 if ( !open() ) { return ConnectionDisconnected; }
00128
00129 int bytes_read = ::recv(client_socket_fd, s, n, 0);
00130 if ( bytes_read < 0 ) {
00131 ecl_debug_throw(devices::receive_exception(LOC));
00132 error_handler = devices::receive_error();
00133 return ConnectionProblem;
00134 }
00135
00136 if ( bytes_read == 0 ) {
00137
00138 close();
00139 return ConnectionHungUp;
00140 }
00141 error_handler = NoError;
00142 return bytes_read;
00143 }
00144
00145 long SocketServer::peek(char *s, const unsigned long &n) ecl_debug_throw_decl(StandardException) {
00146
00147 int bytes_read = ::recv(client_socket_fd, s, n, MSG_PEEK);
00148 if ( bytes_read < 0 ) {
00149 ecl_debug_throw(devices::receive_exception(LOC));
00150 error_handler = devices::receive_error();
00151 return ConnectionProblem;
00152 }
00153 error_handler = NoError;
00154 return bytes_read;
00155 };
00156
00157 long SocketServer::remaining() {
00158 unsigned long bytes;
00159 int result = ioctl(client_socket_fd, FIONREAD, &bytes);
00160 if ( result == -1 ) {
00161 ecl_debug_throw(devices::ioctl_exception(LOC));
00162 error_handler = devices::ioctl_error();
00163 return ConnectionProblem;
00164 }
00165 error_handler = NoError;
00166 return bytes;
00167 };
00168
00169
00170
00171
00172
00173
00174 long SocketServer::write(const char *s, unsigned long n) ecl_debug_throw_decl(StandardException) {
00175 #ifdef MSG_NOSIGNAL
00176 int bytes_written = ::send(client_socket_fd,s,n,0|MSG_NOSIGNAL);
00177 #else
00178 int bytes_written = ::send(client_socket_fd,s,n,0);
00179 #endif
00180 if ( bytes_written < 0 ) {
00181 switch(errno) {
00182 case ( EPIPE ) : {
00183 close();
00184 return ConnectionHungUp;
00185 }
00186 default : {
00187 ecl_debug_throw( devices::send_exception(LOC) );
00188 error_handler = devices::send_error();
00189 return ConnectionProblem;
00190 }
00191 }
00192 }
00193 error_handler = NoError;
00194 return bytes_written;
00195 }
00196
00197 }
00198
00199 #endif
00200 #endif