src/Network/Socket.hh
changeset 380 d193dd1d8a7e
parent 378 5589abf5e61b
child 381 9b35bc329d23
equal deleted inserted replaced
379:2a8e780844d2 380:d193dd1d8a7e
     1 #ifndef NETWORK_SOCKET_HH
     1 #ifndef NETWORK_SOCKET_HH
     2 #define NETWORK_SOCKET_HH
     2 #define NETWORK_SOCKET_HH
     3 
     3 
       
     4 // forward-declare
       
     5 class NetworkSocket;
       
     6 
     4 #include "../Error.hh"
     7 #include "../Error.hh"
     5 #include "Address.hh"
     8 #include "Address.hh"
       
     9 #include "Reactor.hh"
     6 
    10 
     7 /*
    11 /*
     8  * Platform-specific includes
    12  * Platform-specific includes
     9  */
    13  */
    10 #ifndef WIN32
    14 #ifndef WIN32
    17     #define closesocket close
    21     #define closesocket close
    18 #else
    22 #else
    19     #error "This network code won't compile on win32 :)"
    23     #error "This network code won't compile on win32 :)"
    20 #endif
    24 #endif
    21 
    25 
    22 #include <cerrno>
       
    23 #include <cstring>
       
    24 
       
    25 /**
    26 /**
    26  * We use ClanLib's Socket API, but with our own extensions...
    27  * We use ClanLib's Socket API, but with our own extensions...
    27  */
    28  */
    28 class NetworkSocket {
    29 class NetworkSocket {
    29     private:
    30     private:
       
    31         /**
       
    32          * Socket family/type/protocol
       
    33          */
       
    34         struct socket_type {
       
    35             /** Socket domain */
       
    36             int family;
       
    37 
       
    38             /** Socket type */
       
    39             int socktype;
       
    40 
       
    41             /** Socket protocol */
       
    42             int protocol;
       
    43             
       
    44             /** Simple constructor */
       
    45             socket_type (int family = 0, int socktype = 0, int protocol = 0) : family(family), socktype(socktype), protocol(protocol) { }
       
    46         };
       
    47 
       
    48         /** These are nonzero if given via the constructor, used to filter out unwanted addrinfos */
       
    49         socket_type sock_type;
       
    50 
    30         /** The file descriptor */
    51         /** The file descriptor */
    31         int fd;
    52         int fd;
    32 
    53 
    33         /** Socket domain */
    54         /** Our current type, intialized via constructor, but updated by lazy_socket */
    34         int family;
    55         socket_type type;
    35 
       
    36         /** Socket type */
       
    37         int socktype;
       
    38 
       
    39         /** Socket protocol */
       
    40         int protocol;
       
    41 
    56 
    42         /** 
    57         /** 
    43          * Has the socket been explicitly bind()'d? If so, force ourselves to use this socket in connect().
    58          * Has the socket been explicitly bind()'d? If so, force ourselves to use this socket in connect().
    44          */
    59          */
    45         bool bound;
    60         bool bound : 1;
       
    61 
       
    62         /**
       
    63          * Registered to reactor?
       
    64          */
       
    65         bool registered : 1;
       
    66 
       
    67         /**
       
    68          * Do we want to know about recv()s?
       
    69          */
       
    70         bool want_read : 1;
       
    71 
       
    72         /**
       
    73          * Is the write buffer full?
       
    74          */
       
    75         bool want_write : 1;
       
    76 
       
    77         /**
       
    78          * The reactor that we use, defaults to NetworkReactor::current
       
    79          */
       
    80         NetworkReactor *reactor;
    46 
    81 
    47         /**
    82         /**
    48          * Read/write signals
    83          * Read/write signals
    49          */
    84          */
    50         CL_Signal_v0 _sig_read, _sig_write;
    85         CL_Signal_v0 _sig_read, _sig_write;
    51 
    86 
    52     public:
    87     public:
    53         /**
    88         /**
    54          * Construct a socket of the specific type. Family and protocol can be left as NULL, but type should usually
    89          * Construct a socket of the specific type. Family and protocol can be left as NULL, but type should usually
    55          * be specified.
    90          * be specified. The given reactor is used for polling, defaults to NetworkReactor::current
    56          */
    91          */
    57         NetworkSocket (int family, int socktype, int protocol = 0);
    92         NetworkSocket (int family, int socktype, int protocol = 0, NetworkReactor *reactor = NULL);
    58         
    93         
    59         /**
    94         /**
    60          * Create a socket from the given pre-existing fd
    95          * Create a socket from the given pre-existing fd
    61          */
    96          */
    62         NetworkSocket (int fd);
    97         NetworkSocket (int fd, socket_type type, NetworkReactor *reactor = NULL);
    63 
    98 
    64         /**
    99         /**
    65          * Force-close the socket if it's still open
   100          * Force-close the socket if it's still open
    66          */
   101          */
    67         ~NetworkSocket (void);
   102         ~NetworkSocket (void);
    68 
   103 
    69     private:
   104     private:
    70         // XXX: nocopy
   105         // XXX: nocopy
    71         
   106         
    72         /**
   107         /**
       
   108          * Reset bound+poll
       
   109          */ 
       
   110         void reset (void);
       
   111 
       
   112         /**
    73          * Create a new socket of the given type, unless we already have one
   113          * Create a new socket of the given type, unless we already have one
    74          */
   114          */
    75         void lazy_socket (int family, int type, int protocol);
   115         void lazy_socket (int family, int type, int protocol);
    76         
   116         
    77         /**
   117         /**
    78          * Close, ignoring errors
   118          * Close and reset, ignoring errors
    79          */
   119          */
    80         void force_close (void);
   120         void force_close (void);
    81 
   121 
    82     public:
   122     public:
    83         /**
   123         /**
   136          * @throw NetworkSocketError on error
   176          * @throw NetworkSocketError on error
   137          */
   177          */
   138         size_t recv (char *buf, size_t size, NetworkAddress *src = NULL);
   178         size_t recv (char *buf, size_t size, NetworkAddress *src = NULL);
   139 
   179 
   140         /**
   180         /**
   141          * Close the socket
   181          * Close and reset the socket
   142          */
   182          */
   143         void close (void);
   183         void close (void);
   144 
   184 
   145         /**
   185         /**
   146          * Triggered when socket becomes readable
   186          * Triggered when socket becomes readable
   149 
   189 
   150         /**
   190         /**
   151          * Triggered when socket becomes writeable after a send that returned zero
   191          * Triggered when socket becomes writeable after a send that returned zero
   152          */
   192          */
   153         CL_Signal_v0& sig_write (void) { return _sig_write; }
   193         CL_Signal_v0& sig_write (void) { return _sig_write; }
       
   194 
       
   195         /**
       
   196          * Register to NetworkReactor unless already registered
       
   197          */
       
   198         void register_poll (void);
       
   199 
       
   200         /**
       
   201          * Trigger sig_read() once socket is ready for recv?
       
   202          */
       
   203         void set_poll_read (bool want_read) { this->want_read = want_read; if (!registered) register_poll(); }
       
   204 
       
   205         /**
       
   206          * Trigger sig_write() once socket is ready for send?
       
   207          */
       
   208         void set_poll_write (bool want_write) { this->want_write = want_write; if (!registered) register_poll(); }
       
   209 
       
   210         /**
       
   211          * What events this socket is interested in.
       
   212          */
       
   213         NetworkPollMask get_poll (void) { 
       
   214             return (want_read ? POLL_READ : 0) | (want_write ? POLL_WRITE : 0); 
       
   215         }
       
   216 
       
   217         /**
       
   218          * Notify of events
       
   219          */
       
   220         void notify (NetworkPollMask mask) { 
       
   221             if (mask & POLL_READ) _sig_read();
       
   222             if (mask & POLL_WRITE) _sig_write();
       
   223         }
   154 };
   224 };
   155 
   225 
   156 /**
   226 /**
   157  * Base class for expcetions thrown by socket methods
   227  * Base class for expcetions thrown by socket methods
   158  */
   228  */
   165 };
   235 };
   166 
   236 
   167 /**
   237 /**
   168  * Errno-enabled exception, most common type of NetworkSocketError
   238  * Errno-enabled exception, most common type of NetworkSocketError
   169  */
   239  */
   170 class NetworkSocketOSError : public NetworkSocketError {
   240 class NetworkSocketErrno : public NetworkSocketError {
   171     public:
   241     public:
   172         NetworkSocketOSError (const NetworkSocket &socket, const char *op) :
   242         NetworkSocketErrno (const NetworkSocket &socket, const char *op);
   173             NetworkSocketError(socket, op, strerror(errno)) { }
       
   174 };
   243 };
   175 
   244 
   176 /**
   245 /**
   177  * Recv returned EOF
   246  * Recv returned EOF
   178  */
   247  */