00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef CONEXUSSOCKET_H
00020 #define CONEXUSSOCKET_H
00021
00022 #include <sys/types.h>
00023 #include <utility>
00024
00025 #include <conexus/filedescriptor.h>
00026 #include <conexus/address.h>
00027 #include <conexus/error.h>
00028
00029 #include <iostream>
00030
00035 namespace Conexus
00036 {
00037
00050 class Socket: public FileDescriptor
00051 {
00052 public:
00056 typedef enum SocketState {
00057 BOUND =LASTENDPOINTSTATE<<1,
00058 CONNECTED=LASTENDPOINTSTATE<<2,
00059 LISTENING=LASTENDPOINTSTATE<<3,
00060 ACCEPTED =LASTENDPOINTSTATE<<4,
00061 LASTSOCKETSTATE=ACCEPTED,
00062 } SocketState;
00063
00067 Socket(int domain=-1, int type=-1, int protocol=0) throw ();
00068
00069 virtual ~Socket() throw ();
00070
00081 virtual void open() throw (open_error);
00082
00087 virtual void close(bool force=false) throw (close_error);
00088
00094 virtual void bind() throw (bind_error);
00095
00103 virtual void bind(Conexus::Address& a) throw (bind_error);
00104
00110 virtual void connect() throw (connect_error);
00111
00119 virtual void connect(Address& a) throw (connect_error);
00120
00128 virtual void listen(int backlog=0);
00129
00133 int sd() throw ();
00134
00138 int domain() throw ();
00139
00161 void set_domain(int) throw ();
00162
00166 int type() throw ();
00167
00194 void set_type(int) throw ();
00195
00199 int protocol() throw ();
00200
00205 void set_protocol(int) throw ();
00206
00207 virtual Data read(size_t s = 0) throw (read_error);
00208
00209 virtual ssize_t write(const void* data, size_t size, IOMethod block=BLOCK) throw (write_error);
00210 virtual ssize_t writeto(Address& a, const void* data, size_t size) throw (write_error);
00211
00212
00213 virtual void set_option(int option, bool b);
00214
00215 template <typename T>
00216 void set_option(int level, int optname, T& value);
00217
00218 template <typename T>
00219 void option(int level, int optname, T& value);
00220
00221 virtual void change_state(long states) throw (state_error);
00222
00223 sigc::signal<void> signal_bound()
00224 {
00225 return m_signal_bound;
00226 }
00227 sigc::signal<void> signal_connected()
00228 {
00229 return m_signal_connected;
00230 }
00231 sigc::signal<void> signal_listening()
00232 {
00233 return m_signal_listening;
00234 }
00235
00236 bool is_bound()
00237 {
00238 return m_state&BOUND;
00239 }
00240 bool is_connected()
00241 {
00242 return m_state&CONNECTED;
00243 }
00244 bool is_listening()
00245 {
00246 return m_state&LISTENING;
00247 }
00248 bool is_accepted()
00249 {
00250 return m_state&ACCEPTED;
00251 }
00252
00253 virtual const std::string& object_type() { static std::string s("Conexus::Socket"); return s; }
00254
00255 protected:
00256 int m_domain;
00257 int m_type;
00258 int m_protocol;
00259
00260 virtual void read_thread_main();
00261
00262 virtual void set_state_closed();
00263 virtual void set_state_bound();
00264 virtual void set_state_connected();
00265 virtual void set_state_listening();
00266
00267 sigc::signal<void> m_signal_bound;
00268 sigc::signal<void> m_signal_connected;
00269 sigc::signal<void> m_signal_listening;
00270 };
00271
00272 template <typename T>
00273 inline
00274 void Socket::set_option(int level, int optname, T& value)
00275 {
00276 if ( ! is_bound() )
00277 try
00278 {
00279 change_state(BOUND);
00280 }
00281 catch (error::state::failed)
00282 {
00283 return;
00284 }
00285
00286
00287
00288 ::setsockopt(m_fd, level, optname, &value, sizeof(T));
00289 }
00290
00291 template <typename T>
00292 inline
00293 void Socket::option(int level, int optname, T& value)
00294 {
00295 if ( ! is_bound() )
00296 try
00297 {
00298 change_state(BOUND);
00299 }
00300 catch (error::state::failed)
00301 {
00302 return;
00303 }
00304
00305 socklen_t size = sizeof(T);
00306 ::getsockopt(m_fd, level, optname, &value, &size);
00307 }
00308 }
00309
00310 #endif