24#if !defined(_WIN32) && !defined(__CYGWIN__)
25#include <netinet/in.h>
41 struct hostent *hp = gethostbyname(hostName.c_str());
45 if (hp->h_addr_list ==
nullptr)
48 if (hp->h_addr_list[0] ==
nullptr)
51 struct sockaddr_in *sa_in =
new sockaddr_in;
52 (void)memset(sa_in, 0,
sizeof(
struct sockaddr_in));
53 sa_in->sin_family = AF_INET;
54 sa_in->sin_addr.s_addr = ((
struct in_addr *)(hp->h_addr_list[0]))->s_addr;
55 sa_in->sin_port = htons(port);
58 result.
mData.reset(
reinterpret_cast<struct sockaddr*
>(sa_in));
59 result.
mSize =
sizeof(
struct sockaddr_in);
98 while (ret == -1 && (
errno == EINTR ||
errno == EAGAIN ||
errno == EWOULDBLOCK));
128 if (!sockAddr.isValid())
135 if (::connect(
socketFd, &sockAddr,
int(sockAddr.size())) < 0 &&
errno != EINPROGRESS)
214 typedef std::function<void()> F;
234 thread = std::thread([
this, hostName, port] (std::thread && oldThread)
295 auto code = WSAGetLastError();
297 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
299 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
300 (LPTSTR)&s, 0,
nullptr
305 this->errorString = std::string(ws.begin(), ws.end());
307 this->errorString = s;
311 this->errorString +=
" (" + std::to_string(code) +
")";
314 this->errorString = strerror(
errno);
315 this->errorString +=
" (" + std::to_string(
errno) +
")";
351 d_ptr->timeout = timeout;
356 d_ptr->connectToHost(hostName, port);
361 d_ptr->aboutToClose();
366 return d_ptr->write(data, size);
371 return write(data.data(), data.size());
379 return "ConnectionRefusedError";
381 return "RemoteHostClosedError";
383 return "HostNotFoundError";
385 return "SocketAccessError";
387 return "SocketResourceError";
389 return "SocketTimeoutError";
391 return "DatagramTooLargeError";
393 return "NetworkError";
395 return "AddressInUseError";
397 return "SocketAddressNotAvailableError";
399 return "UnsupportedSocketOperationError";
401 return "UnfinishedSocketOperationError";
403 return "ProxyAuthenticationRequiredError";
405 return "SslHandshakeFailedError";
407 return "ProxyConnectionRefusedError";
409 return "ProxyConnectionClosedError";
411 return "ProxyConnectionTimeoutError";
413 return "ProxyNotFoundError";
415 return "ProxyProtocolError";
417 return "OperationError";
419 return "SslInternalError";
421 return "SslInvalidUserDataError";
423 return "TemporaryError";
425 return "UnknownSocketError";
427 return "UnknownSocketError";
432 return d_ptr->socketError;
437 return sSocketErrorToString(
d_ptr->socketError) +
": " +
d_ptr->errorString;
442 d_ptr->onConnected = callback;
447 d_ptr->onDisconnected = callback;
452 d_ptr->onData = callback;
457 d_ptr->onErrorOccurred = callback;
462 if (
d_ptr->thread.get_id() == std::this_thread::get_id())
468 std::unique_lock<std::mutex> locker(
d_ptr->socketStateMutex);
469 d_ptr->socketStateChanged.wait_for(locker, std::chrono::milliseconds(timeout), [
this]
478 if (
d_ptr->thread.get_id() == std::this_thread::get_id())
484 std::unique_lock<std::mutex> locker(
d_ptr->socketStateMutex);
485 return d_ptr->socketStateChanged.wait_for(locker, std::chrono::milliseconds(timeout), [
this]
494 return reinterpret_cast<int *
>(
d_ptr->socketFd);
510 ssize_t size =
d_ptr->recvSocket(data,
sizeof(data));
528 if (
d_ptr->onConnected)
529 d_ptr->onConnected();
534 if (
d_ptr->onDisconnected)
535 d_ptr->onDisconnected();
541 d_ptr->onData(data, size);
546 if (
d_ptr->onErrorOccurred)
552 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()
virtual ~TcpSocketPrivate()
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)