src/Network/Socket.hh
changeset 399 c7295b72731a
parent 382 190f81d30624
child 400 d64bf28c4340
equal deleted inserted replaced
398:306825786fba 399:c7295b72731a
     1 #ifndef NETWORK_SOCKET_HH
     1 #ifndef NETWORK_SOCKET_HH
     2 #define NETWORK_SOCKET_HH
     2 #define NETWORK_SOCKET_HH
     3 
     3 
       
     4 /**
       
     5  * @file
       
     6  *
       
     7  * Network sockets
       
     8  */
       
     9 
     4 // forward-declare
    10 // forward-declare
     5 class NetworkSocket;
    11 class NetworkSocket;
     6 
    12 
     7 #include "../Error.hh"
    13 #include "../Error.hh"
       
    14 #include "Platform.hh"
     8 #include "Address.hh"
    15 #include "Address.hh"
     9 #include "Reactor.hh"
    16 #include "Reactor.hh"
    10 
    17 
    11 /*
    18 /**
    12  * Platform-specific includes
    19  * This is a socket class that wraps an OS socket filedescriptor and provides the more important socket operations
    13  */
    20  * as methods. The implementation aims to be address-family agnostic, and should thence work with both IPv6 and IPv4.
    14 #ifndef WIN32
    21  *
    15     // linux
    22  * Network addresses are abstracted into the NetworkEndpoint and derived NetworkAddress classes. The bind() and
    16     #include <sys/types.h>
    23  * connect() methods accept a NetworkEndpoint as an argument, which allows them to handle hosts with multiple
    17     #include <sys/socket.h>
    24  * addresses (such as all dual-stack IPv6/IPv4 hosts). Other methods such as accept(), recv() and send() require a
    18     #include <unistd.h>
    25  * NetworkAddress, which encodes a single specific address. Note how these are also useable as arguments to
    19     #include <fcntl.h>
    26  * connect()/bind().
    20     
    27  *
    21     #define closesocket close
    28  * The constructor accepts family/socktype/protocol arguments (as passed to the socket() syscall) which can be used to
    22 #else
    29  * limit which kinds of addresses/sockets will be used. Usually, family can be specified as AF_UNSPEC and socktype as
    23     #error "This network code won't compile on win32 :)"
    30  * either SOCK_STREAM or SOCK_DGRAM - this will let bind()/connect() pick the best IPv6/IPv4 address for use.
    24 #endif
    31  *
    25 
    32  * Note however that a call to bind()/connect() can result to multiple calls to the socket() syscall - this interaction
    26 /**
    33  * is slightly complicated. On a succesfull bind() operation, the resulting socket will be "locked down", meaning that
    27  * We use ClanLib's Socket API, but with our own extensions...
    34  * a later connect() operation will use the same local socket - this restricts the remote address families that are valid.
       
    35  *
       
    36  * The behaviour of send/recv differs from the behaviour of the similarly named syscalls. On failure,
       
    37  * NetworkSocketErrno is thrown, and on EOF, NetworkSocketEOFError. Zero is returned if the syscall returns EAGAIN - in
       
    38  * other words - if a socket is nonblocking and the operation would block. Otherwise, the return value is the same as
       
    39  * for the syscalls - the number of bytes send/received.
       
    40  *
       
    41  * NetworkSockets also support polling for non-blocking operations using NetworkReactor. A socket is associated with a
       
    42  * specific reactor (passed to the constructor, defaults to NetworkReactor::current). This is inherited by accept()'d
       
    43  * sockets. For read/write, NetworkSocket provides a sig_read()/sig_write() signal which will be fired if a socket is
       
    44  * registered using set_poll_read(true)/set_poll_write(true) and the NetworkReactor::poll is run. The internal logic
       
    45  * does not manipulate the poll states. Usually, sig_read will always be enabled (except to throttle incoming traffic),
       
    46  * and sig_write should be enabled after send() returns zero (XXX: provide an automatic mechanism for this?).
    28  */
    47  */
    29 class NetworkSocket {
    48 class NetworkSocket {
    30     private:
    49     private:
    31         /**
    50         /**
    32          * Socket family/type/protocol
    51          * Socket family/type/protocol
    49         socket_type sock_type;
    68         socket_type sock_type;
    50 
    69 
    51         /** The file descriptor */
    70         /** The file descriptor */
    52         int fd;
    71         int fd;
    53 
    72 
    54         /** Our current type, intialized via constructor, but updated by lazy_socket */
    73         /** Our current type as used for fd, intialized via constructor, but updated by lazy_socket */
    55         socket_type type;
    74         socket_type type;
    56 
    75 
    57         /** 
    76         /** 
    58          * Has the socket been explicitly bind()'d? If so, force ourselves to use this socket in connect().
    77          * Has the socket been explicitly bind()'d? If so, force ourselves to use this socket in connect().
    59          */
    78          */
   100          * Force-close the socket if it's still open
   119          * Force-close the socket if it's still open
   101          */
   120          */
   102         ~NetworkSocket (void);
   121         ~NetworkSocket (void);
   103 
   122 
   104     private:
   123     private:
   105         // XXX: nocopy
   124         // nocopy
       
   125         NetworkSocket (const NetworkSocket &copy);
       
   126         NetworkSocket &operator= (const NetworkSocket &copy);
   106         
   127         
   107         /**
   128         /**
   108          * Reset bound+poll
   129          * Reset bound+poll
   109          */ 
   130          */ 
   110         void reset (void);
   131         void reset (void);