mirror of https://github.com/JAJames/Jupiter.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
556 lines
16 KiB
556 lines
16 KiB
/**
|
|
* Copyright (C) Justin James - All Rights Reserved.
|
|
* Unauthorized use or copying of this file via any medium is strictly prohibited.
|
|
* This document is proprietary and confidential.
|
|
* This document should be immediately destroyed unless given explicit permission by Justin James.
|
|
* Written by Justin James <justin.aj@hotmail.com>
|
|
*/
|
|
|
|
#include <cstdio>
|
|
|
|
#if defined _WIN32
|
|
#include <WinSock2.h>
|
|
#include <ws2tcpip.h>
|
|
#pragma comment(lib, "Ws2_32.lib")
|
|
bool socketInit = false;
|
|
#else // _WIN32
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <arpa/inet.h>
|
|
#include <netdb.h>
|
|
#include <cstring>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
typedef int SOCKET;
|
|
#define INVALID_SOCKET (SOCKET)(~0)
|
|
#define SOCKET_ERROR (-1)
|
|
#endif // _WIN32
|
|
|
|
#include "Socket.h"
|
|
#include "Functions.h" // makestr()
|
|
#include "CString.h"
|
|
|
|
struct Jupiter::Socket::Data
|
|
{
|
|
SOCKET rawSock;
|
|
unsigned short port;
|
|
Jupiter::CStringS host;
|
|
char *buff;
|
|
size_t bufflen;
|
|
int sockType;
|
|
int sockProto;
|
|
#if defined _WIN32
|
|
unsigned long blockMode = 0;
|
|
#endif
|
|
Data(char *buffer, size_t bufferSize);
|
|
Data(const Data &);
|
|
~Data();
|
|
};
|
|
|
|
Jupiter::Socket::Data::Data(char *buffer, size_t bufferSize)
|
|
{
|
|
Jupiter::Socket::Data::buff = buffer;
|
|
Jupiter::Socket::Data::bufflen = bufferSize;
|
|
Jupiter::Socket::Data::port = 0;
|
|
Jupiter::Socket::Data::rawSock = 0;
|
|
Jupiter::Socket::Data::sockType = SOCK_RAW;
|
|
Jupiter::Socket::Data::sockProto = IPPROTO_RAW;
|
|
for (unsigned int i = 0; i < Jupiter::Socket::Data::bufflen; i++) Jupiter::Socket::Data::buff[i] = 0;
|
|
}
|
|
|
|
Jupiter::Socket::Data::Data(const Data &source)
|
|
{
|
|
Jupiter::Socket::Data::bufflen = source.bufflen;
|
|
Jupiter::Socket::Data::buff = new char[Jupiter::Socket::Data::bufflen];
|
|
Jupiter::Socket::Data::port = source.port;
|
|
Jupiter::Socket::Data::rawSock = source.rawSock;
|
|
Jupiter::Socket::Data::sockType = source.sockType;
|
|
Jupiter::Socket::Data::sockProto = source.sockProto;
|
|
Jupiter::Socket::Data::host = source.host;
|
|
#if defined _WIN32
|
|
Jupiter::Socket::Data::blockMode = source.blockMode;
|
|
#endif
|
|
for (unsigned int i = 0; i < Jupiter::Socket::Data::bufflen; i++) Jupiter::Socket::Data::buff[i] = 0;
|
|
}
|
|
|
|
Jupiter::Socket::Data::~Data()
|
|
{
|
|
if (Jupiter::Socket::Data::buff != nullptr) delete[] Jupiter::Socket::Data::buff;
|
|
}
|
|
|
|
Jupiter::Socket::Socket() : Jupiter::Socket::Socket(4096)
|
|
{
|
|
}
|
|
|
|
Jupiter::Socket::Socket(size_t bufferSize)
|
|
{
|
|
Jupiter::Socket::data_ = new Jupiter::Socket::Data(new char[bufferSize], bufferSize);
|
|
}
|
|
|
|
Jupiter::Socket::Socket(Jupiter::Socket &&source)
|
|
{
|
|
Jupiter::Socket::data_ = source.data_;
|
|
source.data_ = nullptr;
|
|
}
|
|
|
|
Jupiter::Socket::Socket(char *buffer, size_t bufferSize)
|
|
{
|
|
Jupiter::Socket::data_ = new Jupiter::Socket::Data(buffer, bufferSize);
|
|
}
|
|
|
|
Jupiter::Socket::~Socket()
|
|
{
|
|
if (Jupiter::Socket::data_ != nullptr)
|
|
{
|
|
if (Jupiter::Socket::data_->rawSock > 0)
|
|
{
|
|
Jupiter::Socket::closeSocket();
|
|
}
|
|
delete Jupiter::Socket::data_;
|
|
}
|
|
}
|
|
|
|
int Jupiter::Socket::getDescriptor() const
|
|
{
|
|
return Jupiter::Socket::data_->rawSock;
|
|
}
|
|
|
|
void Jupiter::Socket::setDescriptor(int descriptor)
|
|
{
|
|
Jupiter::Socket::data_->rawSock = descriptor;
|
|
}
|
|
|
|
void Jupiter::Socket::setType(int type)
|
|
{
|
|
Jupiter::Socket::data_->sockType = type;
|
|
}
|
|
|
|
void Jupiter::Socket::setProtocol(int proto)
|
|
{
|
|
Jupiter::Socket::data_->sockProto = proto;
|
|
}
|
|
|
|
int Jupiter::Socket::getType() const
|
|
{
|
|
return Jupiter::Socket::data_->sockType;
|
|
}
|
|
|
|
int Jupiter::Socket::getProtocol() const
|
|
{
|
|
return Jupiter::Socket::data_->sockProto;
|
|
}
|
|
|
|
bool Jupiter::Socket::connectToHost(addrinfo *info)
|
|
{
|
|
#if defined _WIN32
|
|
if (!socketInit && !Jupiter::Socket::init()) return false;
|
|
#endif // _WIN32
|
|
Jupiter::Socket::data_->rawSock = socket(info->ai_family, Jupiter::Socket::data_->sockType, Jupiter::Socket::data_->sockProto);
|
|
if (Jupiter::Socket::data_->rawSock == INVALID_SOCKET || (Jupiter::Socket::data_->sockType != SOCK_RAW && Jupiter::Socket::data_->sockProto != IPPROTO_RAW && connect(Jupiter::Socket::data_->rawSock, info->ai_addr, info->ai_addrlen) == SOCKET_ERROR)) return false;
|
|
return true;
|
|
}
|
|
|
|
bool Jupiter::Socket::connectToHost(const char *hostname, unsigned short iPort, const char *clientAddress, unsigned short clientPort)
|
|
{
|
|
#if defined _WIN32
|
|
if (!socketInit && !Jupiter::Socket::init()) return false;
|
|
#endif // _WIN32
|
|
Jupiter::Socket::data_->host.set(hostname);
|
|
Jupiter::Socket::data_->port = iPort;
|
|
int i = 0;
|
|
static char portString[256];
|
|
sprintf(portString, "%hu", Jupiter::Socket::data_->port);
|
|
addrinfo *info = Jupiter::Socket::getAddrInfo(Jupiter::Socket::data_->host.c_str(), portString);
|
|
while (info != nullptr)
|
|
{
|
|
addrinfo *ainfo = Jupiter::Socket::getAddrInfo(info, i);
|
|
if (ainfo == nullptr)
|
|
{
|
|
Jupiter::Socket::freeAddrInfo(info);
|
|
return false;
|
|
}
|
|
sockaddr *asock = ainfo->ai_addr;
|
|
Jupiter::Socket::data_->rawSock = socket(ainfo->ai_family, Jupiter::Socket::data_->sockType, Jupiter::Socket::data_->sockProto);
|
|
if (Jupiter::Socket::data_->rawSock == INVALID_SOCKET) continue;
|
|
if (clientAddress != nullptr) this->bindToPort(clientAddress, clientPort, false);
|
|
if (connect(Jupiter::Socket::data_->rawSock, asock, ainfo->ai_addrlen) == SOCKET_ERROR)
|
|
{
|
|
i++;
|
|
continue;
|
|
}
|
|
Jupiter::Socket::freeAddrInfo(info);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Jupiter::Socket::bindToPort(const char *hostname, unsigned short iPort, bool andListen)
|
|
{
|
|
#if defined _WIN32
|
|
if (!socketInit && !Jupiter::Socket::init()) return false;
|
|
#endif // _WIN32
|
|
Jupiter::Socket::data_->host.set(hostname);
|
|
Jupiter::Socket::data_->port = iPort;
|
|
int i = 0;
|
|
static char portString[256];
|
|
sprintf(portString, "%hu", Jupiter::Socket::data_->port);
|
|
addrinfo *info = Jupiter::Socket::getAddrInfo(Jupiter::Socket::data_->host.c_str(), portString);
|
|
while (info != nullptr)
|
|
{
|
|
addrinfo *ainfo = Jupiter::Socket::getAddrInfo(info, i);
|
|
if (ainfo == nullptr)
|
|
{
|
|
Jupiter::Socket::freeAddrInfo(info);
|
|
return false;
|
|
}
|
|
Jupiter::Socket::data_->rawSock = socket(ainfo->ai_family, Jupiter::Socket::data_->sockType, Jupiter::Socket::data_->sockProto);
|
|
if (Jupiter::Socket::data_->rawSock == INVALID_SOCKET || bind(Jupiter::Socket::data_->rawSock, ainfo->ai_addr, ainfo->ai_addrlen) == SOCKET_ERROR)
|
|
{
|
|
i++;
|
|
continue;
|
|
}
|
|
Jupiter::Socket::freeAddrInfo(info);
|
|
if (andListen && Jupiter::Socket::data_->sockType == SOCK_STREAM && listen(Jupiter::Socket::data_->rawSock, SOMAXCONN) == SOCKET_ERROR) return false;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void Jupiter::Socket::closeSocket()
|
|
{
|
|
if (Jupiter::Socket::data_ != nullptr)
|
|
{
|
|
shutdown(Jupiter::Socket::data_->rawSock, 2);
|
|
#if defined _WIN32
|
|
closesocket(Jupiter::Socket::data_->rawSock);
|
|
#else // _WIN32
|
|
close(Jupiter::Socket::data_->rawSock);
|
|
#endif // _WIN32
|
|
Jupiter::Socket::data_->rawSock = 0;
|
|
}
|
|
}
|
|
|
|
addrinfo *Jupiter::Socket::getAddrInfo(const char *hostname, const char *port) // static
|
|
{
|
|
addrinfo *ptr;
|
|
if (getaddrinfo(hostname, port, nullptr, &ptr)) return nullptr;
|
|
return ptr;
|
|
}
|
|
|
|
addrinfo *Jupiter::Socket::getStaticAddrInfo(const char *hostname, const char *port) // static
|
|
{
|
|
static addrinfo *ptr = nullptr;
|
|
if (ptr != nullptr) freeaddrinfo(ptr);
|
|
ptr = Jupiter::Socket::getAddrInfo(hostname, port);
|
|
return ptr;
|
|
}
|
|
|
|
void Jupiter::Socket::freeAddrInfo(addrinfo *info) // static
|
|
{
|
|
freeaddrinfo(info);
|
|
}
|
|
|
|
addrinfo *Jupiter::Socket::getAddrInfo(addrinfo *addr, int result) // static
|
|
{
|
|
addrinfo *ptr = addr;
|
|
for (int i = 0; i < result && ptr != nullptr; i++) ptr = ptr->ai_next;
|
|
return ptr;
|
|
}
|
|
|
|
char *Jupiter::Socket::resolveAddress(const addrinfo *addr) // static
|
|
{
|
|
char *resolved = new char[NI_MAXHOST];
|
|
getnameinfo(addr->ai_addr, addr->ai_addrlen, resolved, NI_MAXHOST, 0, 0, NI_NUMERICHOST);
|
|
return resolved;
|
|
}
|
|
|
|
char *Jupiter::Socket::resolveAddress(addrinfo *addr, int result) // static
|
|
{
|
|
addrinfo *ptr = Jupiter::Socket::getAddrInfo(addr, result);
|
|
if (ptr == nullptr) return nullptr;
|
|
return Jupiter::Socket::resolveAddress(ptr);
|
|
}
|
|
|
|
char *Jupiter::Socket::resolveAddress(const char *hostname, int result) // static
|
|
{
|
|
addrinfo *info = Jupiter::Socket::getAddrInfo(hostname, 0);
|
|
if (info == nullptr) return nullptr;
|
|
return Jupiter::Socket::resolveAddress(info, result);
|
|
}
|
|
|
|
char *Jupiter::Socket::resolveHostname(addrinfo *addr) // static
|
|
{
|
|
char *resolved = new char[NI_MAXHOST];
|
|
getnameinfo(addr->ai_addr, addr->ai_addrlen, resolved, NI_MAXHOST, 0, 0, 0);
|
|
return resolved;
|
|
}
|
|
|
|
char *Jupiter::Socket::resolveHostname(addrinfo *addr, int result) // static
|
|
{
|
|
addrinfo *ptr = Jupiter::Socket::getAddrInfo(addr, result);
|
|
if (ptr == nullptr) return nullptr;
|
|
return Jupiter::Socket::resolveHostname(ptr);
|
|
}
|
|
|
|
char *Jupiter::Socket::resolveHostname(const char *hostname, int result) // static
|
|
{
|
|
addrinfo *info = Jupiter::Socket::getAddrInfo(hostname, 0);
|
|
if (info == nullptr) return nullptr;
|
|
return Jupiter::Socket::resolveHostname(info, result);
|
|
}
|
|
|
|
Jupiter::Socket *Jupiter::Socket::acceptConnection()
|
|
{
|
|
SOCKET tSock = accept(Socket::data_->rawSock, 0, 0);
|
|
if (tSock != INVALID_SOCKET)
|
|
{
|
|
Socket *r = new Socket(Jupiter::Socket::data_->bufflen);
|
|
r->data_->rawSock = tSock;
|
|
r->data_->sockType = Jupiter::Socket::data_->sockType;
|
|
r->data_->sockProto = Jupiter::Socket::data_->sockProto;
|
|
return r;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
bool Jupiter::Socket::setReadTimeout(unsigned long milliseconds)
|
|
{
|
|
#if defined _WIN32
|
|
return setsockopt(Jupiter::Socket::data_->rawSock, SOL_SOCKET, SO_RCVTIMEO, (const char *)milliseconds, sizeof(milliseconds)) == 0;
|
|
#else // _WIN32
|
|
timeval time;
|
|
time.tv_sec = milliseconds / 1000;
|
|
time.tv_usec = (milliseconds % 1000) * 1000;
|
|
return setsockopt(Jupiter::Socket::data_->rawSock, SOL_SOCKET, SO_RCVTIMEO, (const void *) &time, sizeof(time)) == 0;
|
|
#endif // _WIN32
|
|
}
|
|
|
|
bool Jupiter::Socket::setSendTimeout(unsigned long milliseconds)
|
|
{
|
|
#if defined _WIN32
|
|
return setsockopt(Jupiter::Socket::data_->rawSock, SOL_SOCKET, SO_SNDTIMEO, (const char *)milliseconds, sizeof(milliseconds)) == 0;
|
|
#else // _WIN32
|
|
timeval time;
|
|
time.tv_sec = milliseconds / 1000;
|
|
time.tv_usec = (milliseconds % 1000) * 1000;
|
|
return setsockopt(Jupiter::Socket::data_->rawSock, SOL_SOCKET, SO_SNDTIMEO, (const void *) &time, sizeof(time)) == 0;
|
|
#endif // _WIN32
|
|
}
|
|
|
|
bool Jupiter::Socket::setTimeout(unsigned long milliseconds)
|
|
{
|
|
if (Jupiter::Socket::setReadTimeout(milliseconds) && Jupiter::Socket::setSendTimeout(milliseconds)) return true;
|
|
return false;
|
|
}
|
|
|
|
bool Jupiter::Socket::setBlocking(bool mode)
|
|
{
|
|
#if defined _WIN32
|
|
Jupiter::Socket::data_->blockMode = !mode;
|
|
return ioctlsocket(Jupiter::Socket::data_->rawSock, FIONBIO, &Jupiter::Socket::data_->blockMode) == 0;
|
|
#else // _WIN32
|
|
int flags = fcntl(Jupiter::Socket::data_->rawSock, F_GETFL, 0);
|
|
if (flags < 0) return 0;
|
|
flags = mode ? (flags|O_NONBLOCK) : (flags&~O_NONBLOCK);
|
|
return fcntl(Jupiter::Socket::data_->rawSock, F_SETFL, flags) == 0;
|
|
#endif // _WIN32
|
|
}
|
|
|
|
bool Jupiter::Socket::getBlockingMode() const
|
|
{
|
|
#if defined _WIN32
|
|
return !Jupiter::Socket::data_->blockMode;
|
|
#else // _WIN32
|
|
int flags = fcntl(sock_fd, F_GETFL, 0);
|
|
if (flags == -1) return false;
|
|
return !(flags & O_NONBLOCK);
|
|
#endif
|
|
}
|
|
|
|
const Jupiter::ReadableString &Jupiter::Socket::getHostname() const
|
|
{
|
|
return Jupiter::Socket::data_->host;
|
|
}
|
|
|
|
const char *Jupiter::Socket::getHost() const
|
|
{
|
|
return Jupiter::Socket::data_->host.c_str();
|
|
}
|
|
|
|
unsigned short Jupiter::Socket::getPort() const
|
|
{
|
|
return Jupiter::Socket::data_->port;
|
|
}
|
|
|
|
const char *Jupiter::Socket::getBuffer() const
|
|
{
|
|
return Jupiter::Socket::data_->buff;
|
|
}
|
|
|
|
void Jupiter::Socket::setBuffer(char *buffer, size_t size)
|
|
{
|
|
if (Jupiter::Socket::data_->buff != nullptr) delete[] Jupiter::Socket::data_->buff;
|
|
Jupiter::Socket::data_->bufflen = size;
|
|
Jupiter::Socket::data_->buff = buffer;
|
|
}
|
|
|
|
char *Jupiter::Socket::setBufferSize(size_t size)
|
|
{
|
|
if (Jupiter::Socket::data_->buff != nullptr) delete[] Jupiter::Socket::data_->buff;
|
|
Jupiter::Socket::data_->bufflen = size;
|
|
Jupiter::Socket::data_->buff = new char[Jupiter::Socket::data_->bufflen];
|
|
return Jupiter::Socket::data_->buff;
|
|
}
|
|
|
|
size_t Jupiter::Socket::getBufferSize() const
|
|
{
|
|
return Jupiter::Socket::data_->bufflen;
|
|
}
|
|
|
|
const char *Jupiter::Socket::getData()
|
|
{
|
|
if (this->recv() > 0) return this->getBuffer();
|
|
return nullptr;
|
|
}
|
|
|
|
const char *Jupiter::Socket::getLocalHostname() // static
|
|
{
|
|
static char localHostname[NI_MAXHOST];
|
|
gethostname(localHostname, NI_MAXHOST);
|
|
return localHostname;
|
|
}
|
|
|
|
void Jupiter::Socket::clearBuffer()
|
|
{
|
|
for (unsigned int i = 0; i < Jupiter::Socket::data_->bufflen; i++) Jupiter::Socket::data_->buff[i] = 0;
|
|
}
|
|
|
|
int Jupiter::Socket::send(const char *data, size_t datalen)
|
|
{
|
|
return ::send(Jupiter::Socket::data_->rawSock, data, datalen, 0);
|
|
}
|
|
|
|
int Jupiter::Socket::send(const Jupiter::ReadableString &str)
|
|
{
|
|
return this->send(str.ptr(), str.size());
|
|
}
|
|
|
|
int Jupiter::Socket::send(const char *msg)
|
|
{
|
|
return this->send(msg, strlen(msg));
|
|
}
|
|
|
|
int Jupiter::Socket::sendTo(const addrinfo *info, const char *data, size_t datalen)
|
|
{
|
|
return sendto(Jupiter::Socket::data_->rawSock, data, datalen, 0, info->ai_addr, info->ai_addrlen);
|
|
}
|
|
|
|
int Jupiter::Socket::sendTo(const addrinfo *info, const char *msg)
|
|
{
|
|
return sendto(Jupiter::Socket::data_->rawSock, msg, strlen(msg), 0, info->ai_addr, info->ai_addrlen);
|
|
}
|
|
|
|
int Jupiter::Socket::sendData(const char *data, size_t datalen)
|
|
{
|
|
return this->send(data, datalen);
|
|
}
|
|
|
|
int Jupiter::Socket::sendData(const char *msg)
|
|
{
|
|
return this->send(msg);
|
|
}
|
|
|
|
int Jupiter::Socket::peek()
|
|
{
|
|
int r = ::recv(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buff, Jupiter::Socket::data_->bufflen - 1, MSG_PEEK);
|
|
if (r >= 0) Jupiter::Socket::data_->buff[r] = 0;
|
|
return r;
|
|
}
|
|
|
|
int Jupiter::Socket::peekFrom(addrinfo *info)
|
|
{
|
|
if (info == nullptr) return recvfrom(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buff, Jupiter::Socket::data_->bufflen - 1, 0, nullptr, nullptr);
|
|
socklen_t len = info->ai_addrlen;
|
|
if (len <= 0)
|
|
{
|
|
info->ai_addr = new sockaddr();
|
|
len = sizeof(sockaddr);
|
|
}
|
|
int r = recvfrom(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buff, Jupiter::Socket::data_->bufflen - 1, MSG_PEEK, info->ai_addr, &len);
|
|
if (r >= 0)
|
|
{
|
|
Jupiter::Socket::data_->buff[r] = 0;
|
|
info->ai_addrlen = len;
|
|
info->ai_canonname = nullptr;
|
|
info->ai_family = info->ai_addr->sa_family;
|
|
info->ai_flags = 0;
|
|
info->ai_next = nullptr;
|
|
info->ai_protocol = this->getProtocol();
|
|
info->ai_socktype = this->getType();
|
|
}
|
|
return r;
|
|
}
|
|
|
|
int Jupiter::Socket::recv()
|
|
{
|
|
int r = ::recv(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buff, Jupiter::Socket::data_->bufflen - 1, 0);
|
|
if (r >= 0) Jupiter::Socket::data_->buff[r] = 0;
|
|
return r;
|
|
}
|
|
|
|
int Jupiter::Socket::recvFrom(addrinfo *info)
|
|
{
|
|
if (info == nullptr) return recvfrom(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buff, Jupiter::Socket::data_->bufflen - 1, 0, nullptr, nullptr);
|
|
memset(info, 0, sizeof(addrinfo));
|
|
info->ai_addr = new sockaddr();
|
|
socklen_t len = sizeof(sockaddr);
|
|
int r = recvfrom(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buff, Jupiter::Socket::data_->bufflen-1, 0, info->ai_addr, &len);
|
|
if (r >= 0)
|
|
{
|
|
Jupiter::Socket::data_->buff[r] = 0;
|
|
info->ai_addrlen = len;
|
|
info->ai_family = info->ai_addr->sa_family;
|
|
info->ai_protocol = this->getProtocol();
|
|
info->ai_socktype = this->getType();
|
|
}
|
|
return r;
|
|
}
|
|
|
|
int Jupiter::Socket::receive()
|
|
{
|
|
return this->recv();
|
|
}
|
|
|
|
int Jupiter::Socket::getLastError() // static
|
|
{
|
|
#if defined _WIN32
|
|
int lastError = WSAGetLastError();
|
|
#else // _WIN32
|
|
int lastError = errno;
|
|
#endif // _WIN32
|
|
return lastError;
|
|
}
|
|
|
|
bool Jupiter::Socket::init() // static
|
|
{
|
|
#if defined _WIN32 // _WIN32
|
|
WSADATA wsadata;
|
|
if (WSAStartup(0x0202, &wsadata)) return false;
|
|
if (wsadata.wVersion != 0x0202)
|
|
{
|
|
WSACleanup();
|
|
return false;
|
|
}
|
|
socketInit = true;
|
|
#endif // _WIN32
|
|
return true;
|
|
}
|
|
|
|
bool Jupiter::Socket::cleanup() // static
|
|
{
|
|
#if defined _WIN32 // _WIN32
|
|
WSACleanup();
|
|
#endif // _WIN32
|
|
return true;
|
|
}
|