X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2FMoof%2FSocket.hh;h=60fd8e054531aa080f7cc1740d6075664f3ffb18;hp=a4cb310b3403b4183562354dedbc54d56ab24738;hb=299af4f2047e767e5d79501c26444473bda64c64;hpb=125f447cdb6cf668004e072510674ced91764ffb diff --git a/src/Moof/Socket.hh b/src/Moof/Socket.hh index a4cb310..60fd8e0 100644 --- a/src/Moof/Socket.hh +++ b/src/Moof/Socket.hh @@ -10,7 +10,7 @@ **************************************************************************/ /** - * \file Network.hh + * \file Socket.hh * Network-related classes, including a reinterpreted sockets API. */ @@ -24,20 +24,24 @@ #include #include +#if HAVE_FCNTL_H +#include +#else +#error No alternative to fcntl implemented yet. +#endif + #if defined(_WIN32) #include #include #include +#define SHUT_RD SD_RECEIVE +#define SHUT_WR SD_SEND +#define SHUT_RDWR SD_BOTH #else #include #include #include #include -#if HAVE_FCNTL_H -#include -#else -#include -#endif #endif #include @@ -45,8 +49,12 @@ #include -#ifndef SO_NONBLOCK -#define SO_NONBLOCK 1024 +#ifndef AI_ADDRCONFIG +#define AI_ADDRCONFIG 0 +#endif + +#ifndef AI_V4MAPPED +#define AI_V4MAPPED 0 #endif @@ -95,9 +103,9 @@ public: * \param type The type of socket; either SOCK_STREAM or SOCK_DGRAM. * \param family The family; can be AF_INET or AF_INET6. */ - SocketAddress(const std::string& service, - int type = SOCK_STREAM, - int family = AF_UNSPEC) + explicit SocketAddress(const std::string& service, + int type = SOCK_STREAM, + int family = AF_UNSPEC) { init(service, type, family); } @@ -527,10 +535,10 @@ public: * \param family The family; can be AF_INET or AF_INET6. * \param flags The socket options. */ - Socket(const std::string& service, - int type = SOCK_STREAM, - int family = AF_UNSPEC, - int flags = 0) : + explicit Socket(const std::string& service, + int type = SOCK_STREAM, + int family = AF_UNSPEC, + int flags = 0) : mImpl(SocketAddress(service, type, family), flags) {} @@ -636,7 +644,15 @@ public: template int set(int option, const T& value, int level = SOL_SOCKET) { +#if defined(_WIN32) + return setsockopt(mImpl.fd, + level, + option, + reinterpret_cast(&value), + sizeof(value)); +#else return setsockopt(mImpl.fd, level, option, &value, sizeof(value)); +#endif } /** @@ -678,33 +694,49 @@ public: char str[256] = {'\0'}; socklen_t size = sizeof(str); +#if defined(_WIN32) + int result = getsockopt(mImpl.fd, + level, + option, + reinterpret_cast(&str), + &size); +#else int result = getsockopt(mImpl.fd, level, option, &str, &size); +#endif value.assign(str, size); return result; } + /** + * Set the socket IO mode to either blocking or non-blocking. + * \param isBlocking True if the socket blocks, false otherwise. + */ void setBlocking(bool isBlocking) { - int value = isBlocking; #ifdef HAVE_FCNTL int flags = fcntl(mImpl.fd, F_GETFL); - fcntl(mImpl.fd, F_SETFL, flags | (value ? O_NONBLOCK : 0)); -#else - ioctl(mImpl.fd, FIONBIO, value); + flags = isBlocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK); + fcntl(mImpl.fd, F_SETFL, flags); +#elif defined(_WIN32) + u_long value = isBlocking; + ioctlsocket(mImpl.fd, FIONBIO, &value); #endif } + /** + * Get whether or not the socket is blocking or non-blocking. If the + * IO mode can't be determined, this method will assume the socket is + * a blocking socket. + * \return True if the socket blocks, false otherwise. + */ bool isBlocking() const { #ifdef HAVE_FCNTL int flags = fcntl(mImpl.fd, F_GETFL); - return flags & O_NONBLOCK; -#else - int value; - ioctl(mImpl.fd, FIONBIO, &value); - return value; + return !(flags & O_NONBLOCK); #endif + return true; } @@ -717,7 +749,13 @@ public: */ ssize_t write(const void* bytes, size_t size, int flags = 0) { +#if defined(_WIN32) + return send(mImpl.fd, + reinterpret_cast(bytes), size, + flags); +#else return send(mImpl.fd, bytes, size, flags); +#endif } /** @@ -729,11 +767,20 @@ public: * \param flags The send options. * \return The number of bytes written. */ - ssize_t write(const void* bytes, size_t size, - const SocketAddress& address, int flags = 0) + ssize_t write(const void* bytes, + size_t size, + const SocketAddress& address, + int flags = 0) { +#if defined(_WIN32) + return sendto(mImpl.fd, + reinterpret_cast(bytes), size, + flags, + address.address(), address.size()); +#else return sendto(mImpl.fd, bytes, size, flags, - address.address(), address.size()); + address.address(), address.size()); +#endif } /** @@ -755,8 +802,9 @@ public: * \param flags The send options. * \return The number of bytes written. */ - ssize_t write(const Packet& packet, const SocketAddress& address, - int flags = 0) + ssize_t write(const Packet& packet, + const SocketAddress& address, + int flags = 0) { return write(packet.bytes(), packet.size(), address, flags); } @@ -771,7 +819,15 @@ public: */ ssize_t read(void* bytes, size_t size, int flags = 0) { - return recv(mImpl.fd, bytes, size, flags); +#if defined(_WIN32) + ssize_t result = recv(mImpl.fd, + reinterpret_cast(bytes), size, + flags); +#else + ssize_t result = recv(mImpl.fd, bytes, size, flags); +#endif + if (result == 0) mImpl.isConnected = false; + return result; } /** @@ -783,8 +839,10 @@ public: * \param flags The recv options. * \return The number of bytes read. */ - ssize_t read(void* bytes, size_t size, SocketAddress& address, - int flags = 0) + ssize_t read(void* bytes, + size_t size, + SocketAddress& address, + int flags = 0) { union { @@ -793,12 +851,23 @@ public: } addr; socklen_t length = sizeof(addr); +#if defined(_WIN32) + ssize_t result = recvfrom(mImpl.fd, + reinterpret_cast(bytes), size, + flags, + &addr.sa, &length); +#else ssize_t result = recvfrom(mImpl.fd, bytes, size, flags, - &addr.sa, &length); + &addr.sa, &length); +#endif if (result != -1) { address = SocketAddress(&addr.sa, length, mImpl.address.type()); } + else if (result == 0) + { + mImpl.isConnected = false; + } return result; } @@ -910,7 +979,7 @@ public: Packet&, const SocketAddress&)> Function; - SocketMultiplexer(Socket sock) : + explicit SocketMultiplexer(Socket sock) : mSocket(sock) {}