38 struct hostent *hp = gethostbyname(hostName.c_str());
42 if (hp->h_addr_list ==
nullptr)
45 if (hp->h_addr_list[0] ==
nullptr)
48 struct sockaddr_in *sa_in =
new sockaddr_in;
49 (void)memset(sa_in, 0,
sizeof(
struct sockaddr_in));
50 sa_in->sin_family = AF_INET;
51 sa_in->sin_addr.s_addr = ((
struct in_addr *)(hp->h_addr_list[0]))->s_addr;
52 sa_in->sin_port = htons(port);
55 result.
mData.reset(
reinterpret_cast<struct sockaddr*
>(sa_in));
56 result.
mSize =
sizeof(
struct sockaddr_in);
86 while (ret == -1 && (
errno == EINTR ||
errno == EAGAIN ||
errno == EWOULDBLOCK));
116 if (!sockAddr.isValid())
123 if (::connect(
socketFd, &sockAddr,
int(sockAddr.size())) < 0 &&
errno != EINPROGRESS)
202 typedef std::function<void()> F;
222 thread = std::thread([
this, hostName, port] (std::thread && oldThread)
283 auto code = WSAGetLastError();
285 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
287 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
288 (LPTSTR)&s, 0,
nullptr
293 this->errorString = std::string(ws.begin(), ws.end());
295 this->errorString = s;
302 this->errorString = strerror(
errno);
339 d_ptr->timeout = timeout;
344 d_ptr->connectToHost(hostName, port);
349 d_ptr->aboutToClose();
354 return d_ptr->write(data, size);
359 return write(data.data(), data.size());
367 return "ConnectionRefusedError";
369 return "RemoteHostClosedError";
371 return "HostNotFoundError";
373 return "SocketAccessError";
375 return "SocketResourceError";
377 return "SocketTimeoutError";
379 return "DatagramTooLargeError";
381 return "NetworkError";
383 return "AddressInUseError";
385 return "SocketAddressNotAvailableError";
387 return "UnsupportedSocketOperationError";
389 return "UnfinishedSocketOperationError";
391 return "ProxyAuthenticationRequiredError";
393 return "SslHandshakeFailedError";
395 return "ProxyConnectionRefusedError";
397 return "ProxyConnectionClosedError";
399 return "ProxyConnectionTimeoutError";
401 return "ProxyNotFoundError";
403 return "ProxyProtocolError";
405 return "OperationError";
407 return "SslInternalError";
409 return "SslInvalidUserDataError";
411 return "TemporaryError";
413 return "UnknownSocketError";
415 return "UnknownSocketError";
420 return d_ptr->socketError;
425 return sSocketErrorToString(
d_ptr->socketError) +
": " +
d_ptr->errorString;
430 d_ptr->onConnected = callback;
435 d_ptr->onDisconnected = callback;
440 d_ptr->onData = callback;
445 d_ptr->onErrorOccurred = callback;
450 if (
d_ptr->thread.get_id() == std::this_thread::get_id())
452 d_ptr->setSocketError(TcpSocket::SocketError::OperationError);
456 std::unique_lock<std::mutex> locker(
d_ptr->socketStateMutex);
457 d_ptr->socketStateChanged.wait_for(locker, std::chrono::milliseconds(timeout), [
this]
466 if (
d_ptr->thread.get_id() == std::this_thread::get_id())
468 d_ptr->setSocketError(TcpSocket::SocketError::OperationError);
472 std::unique_lock<std::mutex> locker(
d_ptr->socketStateMutex);
473 return d_ptr->socketStateChanged.wait_for(locker, std::chrono::milliseconds(timeout), [
this]
482 return reinterpret_cast<int *
>(
d_ptr->socketFd);
498 ssize_t size =
d_ptr->recvSocket(data,
sizeof(data));
516 if (
d_ptr->onConnected)
517 d_ptr->onConnected();
522 if (
d_ptr->onDisconnected)
523 d_ptr->onDisconnected();
529 d_ptr->onData(data, size);
534 if (
d_ptr->onErrorOccurred)
540 d_ptr->setSocketError(socketError);
void setReadEvent(SocketFileDescriptor fd)
void setReadWriteExceptionEvent(SocketFileDescriptor fd)
void setTimeout(int timeout)
bool isReadEvent(SocketFileDescriptor fd) const
std::unique_ptr< struct sockaddr > mData
static bool isUnix(const std::string &hostName)
static const char * unixDomainPrefix
static SocketAddress afUnix(const std::string &hostName)
static SocketAddress afInet(const std::string &hostName, unsigned short port)
bool createSocket(int domain)
SocketFileDescriptor socketFd
TcpSocketPrivate(TcpSocket *parent)
std::atomic< TcpSocket::SocketState > socketState
ssize_t sendSocket(const void *src, size_t size)
std::condition_variable socketStateChanged
bool waitForConnectedSockets()
TcpSocket::SocketError socketError
bool connectSocket(const std::string &hostName, unsigned short port)
void connectToHost(const std::string &hostName, unsigned short port)
void setSocketState(TcpSocket::SocketState state)
ssize_t write(const void *data, size_t size)
void setSocketError(TcpSocket::SocketError error, ErrorType errorType=ErrorTypeSystem, const std::string &errorString="")
std::mutex socketStateMutex
void joinThread(std::thread &thread)
std::atomic< bool > isAboutToClose
std::unique_ptr< TcpSocketPrivate > d_ptr
void onData(const std::function< void(const char *, size_t)> &callback)
bool waitForDisconnected(int timeout=2000) const
virtual void disconnected()
std::string errorString() const
void emitConnected() const
void setConnectionTimeout(int timeout)
void connectToHost(const std::string &hostName, uint16_t port)
@ SslHandshakeFailedError
@ ProxyConnectionRefusedError
@ ProxyConnectionClosedError
@ UnfinishedSocketOperationError
@ SocketAddressNotAvailableError
@ SslInvalidUserDataError
@ UnsupportedSocketOperationError
@ ProxyAuthenticationRequiredError
@ ProxyConnectionTimeoutError
void emitErrorOccurred(SocketError error) const
void emitDisconnected() const
SocketError error() const
void emitData(const char *data, size_t size) const
void setSocketError(SocketError socketError)
int * socketDescriptor() const
void onErrorOccurred(const std::function< void(SocketError)> &callback)
void disconnectFromHost()
ssize_t write(const char *data, size_t size)
void onDisconnected(const std::function< void()> &callback)
bool waitForConnected(int timeout=2000) const
virtual void errorOccurred(SocketError)
void onConnected(const std::function< void()> &callback)
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values