src/Network/Socket.hh
changeset 399 c7295b72731a
parent 382 190f81d30624
child 400 d64bf28c4340
--- a/src/Network/Socket.hh	Fri Jan 16 01:05:34 2009 +0200
+++ b/src/Network/Socket.hh	Fri Jan 16 21:24:45 2009 +0200
@@ -1,30 +1,49 @@
 #ifndef NETWORK_SOCKET_HH
 #define NETWORK_SOCKET_HH
 
+/**
+ * @file
+ *
+ * Network sockets
+ */
+
 // forward-declare
 class NetworkSocket;
 
 #include "../Error.hh"
+#include "Platform.hh"
 #include "Address.hh"
 #include "Reactor.hh"
 
-/*
- * Platform-specific includes
- */
-#ifndef WIN32
-    // linux
-    #include <sys/types.h>
-    #include <sys/socket.h>
-    #include <unistd.h>
-    #include <fcntl.h>
-    
-    #define closesocket close
-#else
-    #error "This network code won't compile on win32 :)"
-#endif
-
 /**
- * We use ClanLib's Socket API, but with our own extensions...
+ * This is a socket class that wraps an OS socket filedescriptor and provides the more important socket operations
+ * as methods. The implementation aims to be address-family agnostic, and should thence work with both IPv6 and IPv4.
+ *
+ * Network addresses are abstracted into the NetworkEndpoint and derived NetworkAddress classes. The bind() and
+ * connect() methods accept a NetworkEndpoint as an argument, which allows them to handle hosts with multiple
+ * addresses (such as all dual-stack IPv6/IPv4 hosts). Other methods such as accept(), recv() and send() require a
+ * NetworkAddress, which encodes a single specific address. Note how these are also useable as arguments to
+ * connect()/bind().
+ *
+ * The constructor accepts family/socktype/protocol arguments (as passed to the socket() syscall) which can be used to
+ * limit which kinds of addresses/sockets will be used. Usually, family can be specified as AF_UNSPEC and socktype as
+ * either SOCK_STREAM or SOCK_DGRAM - this will let bind()/connect() pick the best IPv6/IPv4 address for use.
+ *
+ * Note however that a call to bind()/connect() can result to multiple calls to the socket() syscall - this interaction
+ * is slightly complicated. On a succesfull bind() operation, the resulting socket will be "locked down", meaning that
+ * a later connect() operation will use the same local socket - this restricts the remote address families that are valid.
+ *
+ * The behaviour of send/recv differs from the behaviour of the similarly named syscalls. On failure,
+ * NetworkSocketErrno is thrown, and on EOF, NetworkSocketEOFError. Zero is returned if the syscall returns EAGAIN - in
+ * other words - if a socket is nonblocking and the operation would block. Otherwise, the return value is the same as
+ * for the syscalls - the number of bytes send/received.
+ *
+ * NetworkSockets also support polling for non-blocking operations using NetworkReactor. A socket is associated with a
+ * specific reactor (passed to the constructor, defaults to NetworkReactor::current). This is inherited by accept()'d
+ * sockets. For read/write, NetworkSocket provides a sig_read()/sig_write() signal which will be fired if a socket is
+ * registered using set_poll_read(true)/set_poll_write(true) and the NetworkReactor::poll is run. The internal logic
+ * does not manipulate the poll states. Usually, sig_read will always be enabled (except to throttle incoming traffic),
+ * and sig_write should be enabled after send() returns zero (XXX: provide an automatic mechanism for this?).
  */
 class NetworkSocket {
     private:
@@ -51,7 +70,7 @@
         /** The file descriptor */
         int fd;
 
-        /** Our current type, intialized via constructor, but updated by lazy_socket */
+        /** Our current type as used for fd, intialized via constructor, but updated by lazy_socket */
         socket_type type;
 
         /** 
@@ -102,7 +121,9 @@
         ~NetworkSocket (void);
 
     private:
-        // XXX: nocopy
+        // nocopy
+        NetworkSocket (const NetworkSocket &copy);
+        NetworkSocket &operator= (const NetworkSocket &copy);
         
         /**
          * Reset bound+poll