X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2FMoof%2FSocket.hh;h=fcf1a3edbfc0464395941929c222d699d53a1e91;hp=6b0fa88fa6bbe7a72c52eef4773687f217c4a351;hb=7ade2da0367685e098181d7124c9ba145a010626;hpb=61e441a6b4b7c4b2b14b12a1a2545a04155c719b diff --git a/src/Moof/Socket.hh b/src/Moof/Socket.hh index 6b0fa88..fcf1a3e 100644 --- a/src/Moof/Socket.hh +++ b/src/Moof/Socket.hh @@ -12,6 +12,7 @@ #ifndef _MOOF_SOCKET_HH_ #define _MOOF_SOCKET_HH_ +#include #include #include #include @@ -54,8 +55,8 @@ public: mSize(0), mType(0) { - mAddress.sa.sa_family = AF_UNSPEC; - mAddress.v4.sin_port = 0; + mAddr.sa.sa_family = AF_UNSPEC; + mAddr.in.sin_port = 0; } SocketAddress(const std::string& service, const std::string& name, @@ -73,7 +74,7 @@ public: SocketAddress(const struct addrinfo* addr, const std::string& name) { mType = addr->ai_socktype; - memcpy(&mAddress.sa, addr->ai_addr, addr->ai_addrlen); + memcpy(&mAddr.sa, addr->ai_addr, addr->ai_addrlen); mName = name; mSize = addr->ai_addrlen; } @@ -82,7 +83,7 @@ public: int type = SOCK_STREAM) { mType = type; - memcpy(&mAddress.sa, addr, size); + memcpy(&mAddr.sa, addr, size); mSize = size; setNameFromAddress(); } @@ -121,7 +122,7 @@ public: if (status == 0) { mType = addr->ai_socktype; - memcpy(&mAddress.sa, addr->ai_addr, addr->ai_addrlen); + memcpy(&mAddr.sa, addr->ai_addr, addr->ai_addrlen); mSize = addr->ai_addrlen; if (name != "") mName = name; @@ -134,8 +135,8 @@ public: Mf::logWarning(gai_strerror(status)); mType = 0; mSize = 0; - mAddress.sa.sa_family = AF_UNSPEC; - mAddress.v4.sin_port = 0; + mAddr.sa.sa_family = AF_UNSPEC; + mAddr.in.sin_port = 0; } } @@ -158,7 +159,7 @@ public: unsigned short port() const { - return ntohs(mAddress.v4.sin_port); + return ntohs(mAddr.in.sin_port); } int type() const @@ -168,13 +169,13 @@ public: int family() const { - return mAddress.sa.sa_family; + return mAddr.sa.sa_family; } const struct sockaddr* address() const { - return mSize != 0 ? &mAddress.sa : 0; + return mSize != 0 ? &mAddr.sa : 0; } size_t size() const @@ -202,11 +203,10 @@ public: service.length() > 0 ? service.c_str() : 0, &hints, &list); if (status == 0) { - struct addrinfo* addr = list; - while (addr != 0) + for (struct addrinfo* addr = list; + addr != 0; addr = addr->ai_next) { resolved.push_back(SocketAddress(addr, name)); - addr = addr->ai_next; } freeaddrinfo(list); @@ -214,6 +214,7 @@ public: else { Mf::logWarning(gai_strerror(status)); + return -1; } return 0; @@ -226,10 +227,10 @@ private: { #if defined(_WIN32) // inet_ntop was introduced in Vista - mName = inet_ntoa(mAddress.v4.sin_addr); + mName = inet_ntoa(mAddr.in.sin_addr); #else char name[INET6_ADDRSTRLEN] = {'\0'}; - inet_ntop(mAddress.sa.sa_family, &mAddress.sa, name, sizeof(name)); + inet_ntop(mAddr.sa.sa_family, &mAddr.sa, name, sizeof(name)); mName = name; #endif } @@ -238,10 +239,9 @@ private: union { sockaddr sa; - sockaddr_in v4; - sockaddr_in6 v6; + sockaddr_in in; sockaddr_storage storage; - } mAddress; + } mAddr; size_t mSize; std::string mName; int mType; @@ -250,15 +250,92 @@ private: class Socket { + struct Impl + { + int fd; + bool isConnected; + SocketAddress address; + }; + + public: + Socket() : + mFd(-1), + mIsConnected(false) {} + Socket(const SocketAddress& address) : mFd(-1), - mAddress(address) + mIsConnected(false), + mAddress(address) {} + + Socket(const std::string& service, const std::string& name, + int type = SOCK_STREAM, int family = AF_UNSPEC) : + mFd(-1), + mIsConnected(false), + mAddress(SocketAddress(service, name, type, family)) {} + + Socket(const std::string& service, + int type = SOCK_STREAM, int family = AF_UNSPEC) : + mFd(-1), + mIsConnected(false), + mAddress(SocketAddress(service, type, family)) {} + + + Socket(Socket& move) : + mFd(move.mFd), + mIsConnected(move.mIsConnected), + mAddress(move.mAddress) + { + move.mFd = -1; + move.mIsConnected = false; + } + + Socket(Impl move) : + mFd(move.fd), + mIsConnected(move.isConnected), + mAddress(move.address) {} + + Socket& operator=(Socket& move) { - mFd = socket(address.family(), address.type(), 0); +#if defined(_WIN32) + if (mFd != -1) closesocket(mFd); +#else + if (mFd != -1) close(mFd); +#endif + mFd = move.mFd; + mIsConnected = move.mIsConnected; + mAddress = move.mAddress; + move.mFd = -1; + move.mIsConnected = false; + return *this; } + Socket& operator=(Impl move) + { +#if defined(_WIN32) + if (mFd != -1) closesocket(mFd); +#else + if (mFd != -1) close(mFd); +#endif + mFd = move.fd; + mIsConnected = move.isConnected; + mAddress = move.address; + return *this; + } + + operator Impl() + { + Impl impl; + impl.fd = mFd; + impl.isConnected = mIsConnected; + impl.address = mAddress; + mFd = -1; + mIsConnected = false; + return impl; + } + + ~Socket() { #if defined(_WIN32) @@ -271,7 +348,7 @@ public: bool isConnected() const { - return mFd != -1; + return mIsConnected; } const SocketAddress& address() const @@ -282,11 +359,15 @@ public: int connect() { - return ::connect(mFd, mAddress.address(), mAddress.size()); + if (mFd == -1) mFd = socket(mAddress.family(), mAddress.type(), 0); + int result = ::connect(mFd, mAddress.address(), mAddress.size()); + mIsConnected = result != -1; + return result; } int bind() { + if (mFd == -1) mFd = socket(mAddress.family(), mAddress.type(), 0); return ::bind(mFd, mAddress.address(), mAddress.size()); } @@ -295,14 +376,21 @@ public: return ::listen(mFd, backlog > 0 ? backlog : SOMAXCONN); } - Socket accept() + int accept(Socket& socket) { - return Socket(mFd); + Socket temp = Socket(mFd); + if (temp.mFd != -1) + { + socket = temp; + return socket.mFd; + } + return -1; } int set(int option, int value = 0) { + if (mFd == -1) mFd = socket(mAddress.family(), mAddress.type(), 0); if (option == SO_NONBLOCK) { #ifdef HAVE_FCNTL @@ -317,12 +405,14 @@ public: int set(int option, const std::string& value) { + if (mFd == -1) mFd = socket(mAddress.family(), mAddress.type(), 0); return setsockopt(mFd, SOL_SOCKET, option, - value.c_str(), value.length()); + value.data(), value.length()); } int get(int option, int& value) { + if (mFd == -1) mFd = socket(mAddress.family(), mAddress.type(), 0); if (option == SO_NONBLOCK) { #ifdef HAVE_FCNTL @@ -338,6 +428,7 @@ public: int get(int option, std::string& value) { + if (mFd == -1) mFd = socket(mAddress.family(), mAddress.type(), 0); char str[64] = {'\0'}; socklen_t optlen = sizeof(str); int result = getsockopt(mFd, SOL_SOCKET, option, &str, &optlen); @@ -345,26 +436,35 @@ public: return result; } - void write(const Packet& packet) + + ssize_t write(const void* bytes, size_t size) { - write(mAddress, packet); + return send(mFd, bytes, size, 0); + } + ssize_t write(const void* bytes, size_t size, + const SocketAddress& address) + { + return sendto(mFd, bytes, size, 0, + address.address(), address.size()); } - void write(const SocketAddress& address, const Packet& packet) + ssize_t write(const Packet& packet) { - sendto(mFd, packet.bytes(), packet.size(), 0, - address.address(), address.size()); + return write(packet.bytes(), packet.size()); } - Packet read() + ssize_t write(const Packet& packet, const SocketAddress& address) { - char buffer[1024]; - int size = recv(mFd, buffer, sizeof(buffer), 0); + return write(packet.bytes(), packet.size(), address); + } + - return Packet(buffer, size); + ssize_t read(void* bytes, size_t size) + { + return recv(mFd, bytes, size, 0); } - Packet read(SocketAddress& address) + ssize_t read(void* bytes, size_t size, SocketAddress& address) { union { @@ -373,12 +473,28 @@ public: } addr; socklen_t length = sizeof(addr); - char buffer[1024]; - int size = recvfrom(mFd, buffer, sizeof(buffer), 0, - &addr.sa, &length); + ssize_t result = recvfrom(mFd, bytes, size, 0, &addr.sa, &length); + if (result != -1) + { + address = SocketAddress(&addr.sa, length, mAddress.type()); + } + return result; + } - address = SocketAddress(&addr.sa, length, mAddress.type()); - return Packet(buffer, size); + ssize_t read(Packet& packet) + { + char buffer[65536]; + ssize_t result = read(buffer, sizeof(buffer)); + if (result != -1) packet = Packet(buffer, result); + return result; + } + + ssize_t read(Packet& packet, SocketAddress& address) + { + char buffer[65536]; + ssize_t result = read(buffer, sizeof(buffer), address); + if (result != -1) packet = Packet(buffer, result); + return result; } @@ -395,11 +511,16 @@ private: socklen_t length = sizeof(addr); mFd = ::accept(fd, &addr.sa, &length); - mAddress = SocketAddress(&addr.sa, length); + if (mFd != -1) + { + mIsConnected = true; + mAddress = SocketAddress(&addr.sa, length); + } } int mFd; + bool mIsConnected; SocketAddress mAddress; };