+#ifndef SCD_SOCKET_H
+#define SCD_SOCKET_H
+
+#include <string>
+#include <sys/types.h>
+#include <netdb.h>
+
+const int SCD_MAXCONN = 100;
+
+// forward declaration for friends
+class scd_sock_poller;
+
+/**
+ * Berkeley TCP socket API wrapper class. The socket is put into non blocking
+ * mode.
+ */
+class scd_socket
+{
+ friend class scd_sock_poller;
+
+public:
+ scd_socket();
+ virtual ~scd_socket();
+
+ /**
+ * Returns true if this socket has been successfully created and
+ * has not been closed since then. Use this function to check if an
+ * error occured.
+ */
+ bool is_valid() const;
+
+ /**
+ * Creates the socket.
+ * \return false if the socket is already valid
+ * \exception scd_exception if unexpected errors occured
+ */
+ bool create();
+
+ /**
+ * Closes the socket and marks it as invalid.
+ */
+ void close();
+
+ /**
+ * Binds the socket to a local address and port.
+ * \param loc_name the local IP or hostname or empty string
+ * \param loc_port the local port or 0
+ * \return false if the socket is not valid or an invalid address
+ * was specified
+ * \exception scd_exception if ::bind() failed for unexpected reason
+ */
+ bool bind(const std::string &loc_name, const uint16_t loc_port);
+
+ /**
+ * Binds the socket to a port.
+ * \param loc_port the local port
+ * \exception scd_exception if ::bind() failed for unexpected reason
+ * \return false if the sockat is not valid
+ */
+ bool bind(const uint16_t loc_port);
+
+ /**
+ * Marks a previously bound socket as listening.
+ * \return false if the socket is not valid
+ * \exception scd_exception if ::listen() failed
+ */
+ bool listen();
+
+ /**
+ * Accept a new connection from a listening socket.
+ * \param new_sock the object to hold the new connection
+ * \return true if a new connection was accepted
+ * \exception scd_exception if unexpected errors occured
+ */
+ bool accept(scd_socket &new_sock);
+
+ /**
+ * Initiates a connection attempt to a remote host. Use is_connecting()
+ * to check whether this attempt is still in progress or is_connected()
+ * to check whether the socket is connected. If the connection attempt
+ * is in progress, the socket has to be polled for a write event.
+ * If this event occures its handler shall call connected_event()
+ * to check if the connection was established successully.
+ * It is not possible to try to connect again if the write event
+ * is not polled and processed by calling connected_event() after
+ * is_connecting() has indicated that the attempt is still in progress.
+ * \param rem_name the hostname of the remote host (IP or host name)
+ * \param rem_port the port to connect to
+ * \return true if the connection attempt was started successfully,
+ * false if the hostname could not be resolved or a connection attempt
+ * was not possible
+ * \exception scd_exception if unexpected errors occured
+ */
+ bool connect(const std::string &rem_name, const uint16_t rem_port);
+
+ /**
+ * Indicates if a previous connection attempt is still in progress.
+ * \return true if a conneciton attempt is still in progress
+ */
+ bool is_connecting();
+
+ /**
+ * Indicates if this socket is connected to a peer either while it has
+ * been accepted from an incoming connection or the outgoing connection
+ * is established.
+ * \return true if the socket is valid and connected
+ */
+ bool is_connected();
+
+ /**
+ * Check if a connection attempt has succeeded on a write event. Shall
+ * only be called from the write event handler. Especially after a
+ * connection attempt was in progress. Can also be called if the
+ * connection has already been established.
+ * \return true if the socket is valid and the connection is established
+ * \exception scd_exception if unexpected errors occured
+ */
+ bool connected_event();
+
+ /**
+ * Tries to send at most len data from the buffer.
+ * Might close the socket on errors.
+ * \return the number of successfully sent bytes
+ * \exception scd_exception if unexpected errors occured
+ */
+ size_t send(const void* buf, size_t len);
+
+ /**
+ * Tries to receive at most len data to the buffer.
+ * Might close the socket on errors.
+ * \return the number of successfully received bytes
+ * \exception scd_exception if unexpected errors occured
+ */
+ size_t recv(void* buf, size_t len);
+
+
+private:
+ /* member variables */
+
+ int _socket;
+ bool _is_connecting;
+ bool _is_connected;
+
+ /* member functions */
+
+ /**
+ * Initializes a sockaddr_in struct. Can resolve hostnames.
+ */
+ bool _get_sockaddr(sockaddr_in &addr, const std::string &name,
+ const uint16_t port) const;
+
+ /**
+ * Sets the socket in blocking or non blocking mode.
+ * \param mode true to set blocking mode
+ * \return false if the socket is not valid
+ * \exception scd_exception if unexpected errors occured
+ */
+ bool _set_blocking(const bool mode);
+
+ /**
+ * Disables the Nagle algorithm which buffers outgoing data up to 200ms
+ * before sending it. Disabling causes more network traffic but
+ * decreases the delay.
+ */
+ bool _set_nodelay();
+};
+
+#endif