--- 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 ©);
+ NetworkSocket &operator= (const NetworkSocket ©);
/**
* Reset bound+poll