mirror of
https://github.com/pocoproject/poco.git
synced 2024-12-12 10:13:51 +01:00
* fix(Net): Add Unix socket support on windows #4208 * feat(Net): add abstract local socket support #4208 * fix(PollSet): use localhost socket in PollSet on windows when available #4208 * fix(PollSetTest): comment checking unconnected sockets status (Linux epoll signals them as readable/writable)
This commit is contained in:
parent
c918c70e68
commit
e40f07099d
3
.vscode/c_cpp_properties.json
vendored
3
.vscode/c_cpp_properties.json
vendored
@ -22,7 +22,8 @@
|
|||||||
"${POCO_BASE}/JWT/include",
|
"${POCO_BASE}/JWT/include",
|
||||||
"${POCO_BASE}/Redis/include",
|
"${POCO_BASE}/Redis/include",
|
||||||
"${POCO_BASE}/MongoDB/include",
|
"${POCO_BASE}/MongoDB/include",
|
||||||
"${POCO_BASE}/ApacheConnector/include"
|
"${POCO_BASE}/ApacheConnector/include",
|
||||||
|
"/usr/include"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"configurations": [
|
"configurations": [
|
||||||
|
@ -149,6 +149,10 @@
|
|||||||
|
|
||||||
// No UNIX socket support
|
// No UNIX socket support
|
||||||
// Define to disable unix sockets
|
// Define to disable unix sockets
|
||||||
|
// UNIX local sockets are default-enabled on
|
||||||
|
// all UNIX systems, on Windows if available
|
||||||
|
// See Net/SocketDefs.h
|
||||||
|
// See https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/
|
||||||
// #define POCO_NET_NO_UNIX_SOCKET
|
// #define POCO_NET_NO_UNIX_SOCKET
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,8 +37,11 @@ class IPAddress;
|
|||||||
class Net_API SocketAddress
|
class Net_API SocketAddress
|
||||||
/// This class represents an internet (IP) endpoint/socket
|
/// This class represents an internet (IP) endpoint/socket
|
||||||
/// address. The address can belong either to the
|
/// address. The address can belong either to the
|
||||||
/// IPv4 or the IPv6 address family and consists of a
|
/// IPv4, IPv6 or Unix local family.
|
||||||
/// host address and a port number.
|
/// IP addresses consist of a host address and a port number.
|
||||||
|
/// An Unix local socket address consists of a path to socket file.
|
||||||
|
/// Abstract local sockets, which operate without the need for
|
||||||
|
/// interaction with the filesystem, are supported on Linux only.
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// The following declarations keep the Family type
|
// The following declarations keep the Family type
|
||||||
@ -49,7 +52,7 @@ public:
|
|||||||
#if defined(POCO_HAVE_IPv6)
|
#if defined(POCO_HAVE_IPv6)
|
||||||
static const Family IPv6 = AddressFamily::IPv6;
|
static const Family IPv6 = AddressFamily::IPv6;
|
||||||
#endif
|
#endif
|
||||||
#if defined(POCO_OS_FAMILY_UNIX)
|
#if defined(POCO_HAS_UNIX_SOCKET)
|
||||||
static const Family UNIX_LOCAL = AddressFamily::UNIX_LOCAL;
|
static const Family UNIX_LOCAL = AddressFamily::UNIX_LOCAL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -124,16 +127,30 @@ public:
|
|||||||
/// [::ffff:192.168.1.120]:2040
|
/// [::ffff:192.168.1.120]:2040
|
||||||
/// www.appinf.com:8080
|
/// www.appinf.com:8080
|
||||||
///
|
///
|
||||||
/// On POSIX platforms supporting UNIX_LOCAL sockets, hostAndPort
|
/// On platforms supporting UNIX_LOCAL sockets, hostAndPort
|
||||||
/// can also be the absolute path of a local socket, starting with a
|
/// can also be a valid absolute local socket file path.
|
||||||
/// slash, e.g. "/tmp/local.socket".
|
///
|
||||||
|
/// Examples:
|
||||||
|
/// /tmp/local.sock
|
||||||
|
/// C:\Temp\local.sock
|
||||||
|
///
|
||||||
|
/// On Linux, abstract local sockets are supported as well.
|
||||||
|
/// Abstract local sockets operate in a namespace that has
|
||||||
|
/// no need for a filesystem. They are identified by
|
||||||
|
/// a null byte at the beginning of the path.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
/// \0abstract.sock
|
||||||
|
///
|
||||||
|
|
||||||
SocketAddress(Family family, const std::string& addr);
|
SocketAddress(Family family, const std::string& addr);
|
||||||
/// Creates a SocketAddress of the given family from a
|
/// Creates a SocketAddress of the given family from a
|
||||||
/// string representation of the address, which is
|
/// string representation of the address, which is
|
||||||
/// either an IP address and port number, separated by
|
/// either (1) an IP address and port number, separated by
|
||||||
/// a colon for IPv4 or IPv6 addresses, or a path for
|
/// a colon for IPv4 or IPv6 addresses, or (2) path for
|
||||||
/// UNIX_LOCAL sockets.
|
/// UNIX_LOCAL sockets.
|
||||||
|
/// See `SocketAddress(const string&)` documentation
|
||||||
|
/// for more details.
|
||||||
|
|
||||||
SocketAddress(const SocketAddress& addr);
|
SocketAddress(const SocketAddress& addr);
|
||||||
/// Creates a SocketAddress by copying another one.
|
/// Creates a SocketAddress by copying another one.
|
||||||
@ -181,7 +198,7 @@ public:
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
MAX_ADDRESS_LENGTH =
|
MAX_ADDRESS_LENGTH =
|
||||||
#if defined(POCO_OS_FAMILY_UNIX)
|
#if defined(POCO_HAS_UNIX_SOCKET)
|
||||||
sizeof(struct sockaddr_un)
|
sizeof(struct sockaddr_un)
|
||||||
#elif defined(POCO_HAVE_IPv6)
|
#elif defined(POCO_HAVE_IPv6)
|
||||||
sizeof(struct sockaddr_in6)
|
sizeof(struct sockaddr_in6)
|
||||||
@ -214,7 +231,7 @@ private:
|
|||||||
void newIPv6(const IPAddress& hostAddress, Poco::UInt16 portNumber);
|
void newIPv6(const IPAddress& hostAddress, Poco::UInt16 portNumber);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(POCO_OS_FAMILY_UNIX)
|
#if defined(POCO_HAS_UNIX_SOCKET)
|
||||||
void newLocal(const sockaddr_un* sockAddr);
|
void newLocal(const sockaddr_un* sockAddr);
|
||||||
void newLocal(const std::string& path);
|
void newLocal(const std::string& path);
|
||||||
#endif
|
#endif
|
||||||
@ -265,7 +282,7 @@ inline void SocketAddress::newIPv6(const IPAddress& hostAddress, Poco::UInt16 po
|
|||||||
#endif // POCO_HAVE_IPv6
|
#endif // POCO_HAVE_IPv6
|
||||||
|
|
||||||
|
|
||||||
#if defined(POCO_OS_FAMILY_UNIX)
|
#if defined(POCO_HAS_UNIX_SOCKET)
|
||||||
inline void SocketAddress::newLocal(const sockaddr_un* sockAddr)
|
inline void SocketAddress::newLocal(const sockaddr_un* sockAddr)
|
||||||
{
|
{
|
||||||
_pImpl = new Poco::Net::Impl::LocalSocketAddressImpl(sockAddr);
|
_pImpl = new Poco::Net::Impl::LocalSocketAddressImpl(sockAddr);
|
||||||
@ -276,12 +293,12 @@ inline void SocketAddress::newLocal(const std::string& path)
|
|||||||
{
|
{
|
||||||
_pImpl = new Poco::Net::Impl::LocalSocketAddressImpl(path.c_str(), path.size());
|
_pImpl = new Poco::Net::Impl::LocalSocketAddressImpl(path.c_str(), path.size());
|
||||||
}
|
}
|
||||||
#endif // POCO_OS_FAMILY_UNIX
|
#endif // POCO_HAS_UNIX_SOCKET
|
||||||
|
|
||||||
|
|
||||||
inline bool SocketAddress::operator == (const SocketAddress& socketAddress) const
|
inline bool SocketAddress::operator == (const SocketAddress& socketAddress) const
|
||||||
{
|
{
|
||||||
#if defined(POCO_OS_FAMILY_UNIX)
|
#if defined(POCO_HAS_UNIX_SOCKET)
|
||||||
if (family() == UNIX_LOCAL)
|
if (family() == UNIX_LOCAL)
|
||||||
return toString() == socketAddress.toString();
|
return toString() == socketAddress.toString();
|
||||||
else
|
else
|
||||||
|
@ -177,7 +177,7 @@ inline SocketAddressImpl::Family IPv6SocketAddressImpl::family() const
|
|||||||
#endif // POCO_HAVE_IPv6
|
#endif // POCO_HAVE_IPv6
|
||||||
|
|
||||||
|
|
||||||
#if defined(POCO_OS_FAMILY_UNIX)
|
#if defined(POCO_HAS_UNIX_SOCKET)
|
||||||
|
|
||||||
|
|
||||||
class Net_API LocalSocketAddressImpl: public SocketAddressImpl
|
class Net_API LocalSocketAddressImpl: public SocketAddressImpl
|
||||||
|
@ -30,6 +30,14 @@
|
|||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <ws2def.h>
|
#include <ws2def.h>
|
||||||
|
#if !defined (POCO_NET_NO_UNIX_SOCKET)
|
||||||
|
#if (__cplusplus >= 201703L)
|
||||||
|
#if __has_include(<afunix.h>)
|
||||||
|
#include <afunix.h>
|
||||||
|
#define POCO_HAS_UNIX_SOCKET
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
#define POCO_INVALID_SOCKET INVALID_SOCKET
|
#define POCO_INVALID_SOCKET INVALID_SOCKET
|
||||||
#define poco_socket_t SOCKET
|
#define poco_socket_t SOCKET
|
||||||
#define poco_socklen_t int
|
#define poco_socklen_t int
|
||||||
@ -148,7 +156,6 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#if defined(POCO_OS_FAMILY_UNIX)
|
|
||||||
#if (POCO_OS == POCO_OS_LINUX) || (POCO_OS == POCO_OS_ANDROID)
|
#if (POCO_OS == POCO_OS_LINUX) || (POCO_OS == POCO_OS_ANDROID)
|
||||||
// Net/src/NetworkInterface.cpp changed #include <linux/if.h> to #include <net/if.h>
|
// Net/src/NetworkInterface.cpp changed #include <linux/if.h> to #include <net/if.h>
|
||||||
// no more conflict, can use #include <net/if.h> here
|
// no more conflict, can use #include <net/if.h> here
|
||||||
@ -161,7 +168,6 @@
|
|||||||
#else
|
#else
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
#if (POCO_OS == POCO_OS_SOLARIS) || (POCO_OS == POCO_OS_MAC_OS_X)
|
#if (POCO_OS == POCO_OS_SOLARIS) || (POCO_OS == POCO_OS_MAC_OS_X)
|
||||||
#include <sys/sockio.h>
|
#include <sys/sockio.h>
|
||||||
#include <sys/filio.h>
|
#include <sys/filio.h>
|
||||||
@ -228,6 +234,9 @@
|
|||||||
#define POCO_TRY_AGAIN TRY_AGAIN
|
#define POCO_TRY_AGAIN TRY_AGAIN
|
||||||
#define POCO_NO_RECOVERY NO_RECOVERY
|
#define POCO_NO_RECOVERY NO_RECOVERY
|
||||||
#define POCO_NO_DATA NO_DATA
|
#define POCO_NO_DATA NO_DATA
|
||||||
|
#if !defined (POCO_NET_NO_UNIX_SOCKET)
|
||||||
|
#define POCO_HAS_UNIX_SOCKET
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -389,7 +398,7 @@ struct AddressFamily
|
|||||||
{
|
{
|
||||||
UNKNOWN = AF_UNSPEC,
|
UNKNOWN = AF_UNSPEC,
|
||||||
/// Unspecified family
|
/// Unspecified family
|
||||||
#if defined(POCO_OS_FAMILY_UNIX)
|
#if defined(POCO_HAS_UNIX_SOCKET)
|
||||||
UNIX_LOCAL = AF_UNIX,
|
UNIX_LOCAL = AF_UNIX,
|
||||||
/// UNIX domain socket address family. Available on UNIX/POSIX platforms only.
|
/// UNIX domain socket address family. Available on UNIX/POSIX platforms only.
|
||||||
#endif
|
#endif
|
||||||
|
@ -36,7 +36,8 @@ DatagramSocketImpl::DatagramSocketImpl(SocketAddress::Family family)
|
|||||||
else if (family == SocketAddress::IPv6)
|
else if (family == SocketAddress::IPv6)
|
||||||
init(AF_INET6);
|
init(AF_INET6);
|
||||||
#endif
|
#endif
|
||||||
#if defined(POCO_OS_FAMILY_UNIX)
|
// on windows, UDP is not supported for local sockets
|
||||||
|
#if defined(POCO_OS_FAMILY_UNIX) && defined(POCO_HAS_UNIX_SOCKET)
|
||||||
else if (family == SocketAddress::UNIX_LOCAL)
|
else if (family == SocketAddress::UNIX_LOCAL)
|
||||||
init(AF_UNIX);
|
init(AF_UNIX);
|
||||||
#endif
|
#endif
|
||||||
|
@ -53,7 +53,7 @@ MulticastSocket::MulticastSocket()
|
|||||||
|
|
||||||
MulticastSocket::MulticastSocket(SocketAddress::Family family): DatagramSocket(family)
|
MulticastSocket::MulticastSocket(SocketAddress::Family family): DatagramSocket(family)
|
||||||
{
|
{
|
||||||
#if defined(POCO_OS_FAMILY_UNIX)
|
#if defined(POCO_HAS_UNIX_SOCKET)
|
||||||
if (family == SocketAddress::UNIX_LOCAL)
|
if (family == SocketAddress::UNIX_LOCAL)
|
||||||
throw Poco::InvalidArgumentException("Cannot create a MulticastSocket with UNIX_LOCAL socket");
|
throw Poco::InvalidArgumentException("Cannot create a MulticastSocket with UNIX_LOCAL socket");
|
||||||
#endif
|
#endif
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "Poco/Net/PollSet.h"
|
#include "Poco/Net/PollSet.h"
|
||||||
#include "Poco/Net/SocketImpl.h"
|
#include "Poco/Net/SocketImpl.h"
|
||||||
|
#include "Poco/TemporaryFile.h"
|
||||||
#include "Poco/Mutex.h"
|
#include "Poco/Mutex.h"
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
@ -68,9 +69,14 @@ public:
|
|||||||
using SocketMode = std::pair<Socket, int>;
|
using SocketMode = std::pair<Socket, int>;
|
||||||
using SocketMap = std::map<void*, SocketMode>;
|
using SocketMap = std::map<void*, SocketMode>;
|
||||||
|
|
||||||
PollSetImpl(): _events(1024),
|
static const epoll_event EPOLL_NULL_EVENT;
|
||||||
_port(0),
|
|
||||||
_eventfd(eventfd(_port, 0)),
|
PollSetImpl(): _events(FD_SETSIZE, EPOLL_NULL_EVENT),
|
||||||
|
#if defined(WEPOLL_H_)
|
||||||
|
_eventfd(eventfd()),
|
||||||
|
#else
|
||||||
|
_eventfd(eventfd(0, 0)),
|
||||||
|
#endif // WEPOLL_H_
|
||||||
_epollfd(epoll_create(1))
|
_epollfd(epoll_create(1))
|
||||||
{
|
{
|
||||||
int err = addFD(_eventfd, PollSet::POLL_READ, EPOLL_CTL_ADD);
|
int err = addFD(_eventfd, PollSet::POLL_READ, EPOLL_CTL_ADD);
|
||||||
@ -87,7 +93,6 @@ public:
|
|||||||
~PollSetImpl()
|
~PollSetImpl()
|
||||||
{
|
{
|
||||||
#ifdef WEPOLL_H_
|
#ifdef WEPOLL_H_
|
||||||
if (_eventfd >= 0) eventfd(_port, _eventfd);
|
|
||||||
if (_epollfd) close(_epollfd);
|
if (_epollfd) close(_epollfd);
|
||||||
#else
|
#else
|
||||||
if (_eventfd > 0) close(_eventfd.exchange(0));
|
if (_eventfd > 0) close(_eventfd.exchange(0));
|
||||||
@ -153,10 +158,7 @@ public:
|
|||||||
if (_epollfd < 0) SocketImpl::error();
|
if (_epollfd < 0) SocketImpl::error();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef WEPOLL_H_
|
#ifndef WEPOLL_H_
|
||||||
eventfd(_port, _eventfd);
|
|
||||||
_eventfd = eventfd(_port);
|
|
||||||
#else
|
|
||||||
close(_eventfd.exchange(0));
|
close(_eventfd.exchange(0));
|
||||||
_eventfd = eventfd(0, 0);
|
_eventfd = eventfd(0, 0);
|
||||||
#endif
|
#endif
|
||||||
@ -231,10 +233,16 @@ public:
|
|||||||
|
|
||||||
void wakeUp()
|
void wakeUp()
|
||||||
{
|
{
|
||||||
#ifdef WEPOLL_H_
|
|
||||||
StreamSocket ss(SocketAddress("127.0.0.1", _port));
|
|
||||||
#else
|
|
||||||
uint64_t val = 1;
|
uint64_t val = 1;
|
||||||
|
#ifdef WEPOLL_H_
|
||||||
|
#ifdef POCO_HAS_UNIX_SOCKET
|
||||||
|
poco_check_ptr (_pSockFile);
|
||||||
|
StreamSocket ss(SocketAddress(_pSockFile->path()));
|
||||||
|
#else
|
||||||
|
StreamSocket ss(SocketAddress("127.0.0.1", _port));
|
||||||
|
#endif
|
||||||
|
ss.sendBytes(&val, sizeof(val));
|
||||||
|
#else
|
||||||
// This is guaranteed to write into a valid fd,
|
// This is guaranteed to write into a valid fd,
|
||||||
// or 0 (meaning PollSet is being destroyed).
|
// or 0 (meaning PollSet is being destroyed).
|
||||||
// Errors are ignored.
|
// Errors are ignored.
|
||||||
@ -296,41 +304,46 @@ private:
|
|||||||
return epoll_ctl(_epollfd, op, fd, &ev);
|
return epoll_ctl(_epollfd, op, fd, &ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WEPOLL_H_
|
#ifndef WEPOLL_H_
|
||||||
|
using EPollHandle = std::atomic<int>;
|
||||||
|
#else // WEPOLL_H_
|
||||||
|
using EPollHandle = std::atomic<HANDLE>;
|
||||||
|
|
||||||
int eventfd(int& port, int rmFD = 0)
|
#ifdef POCO_HAS_UNIX_SOCKET
|
||||||
{
|
int eventfd()
|
||||||
if (rmFD == 0)
|
|
||||||
{
|
{
|
||||||
_pSocket = new ServerSocket(SocketAddress("127.0.0.1", 0));
|
if (!_pSockFile)
|
||||||
|
{
|
||||||
|
_pSockFile.reset(new TemporaryFile);
|
||||||
|
_pSocket.reset(new ServerSocket(SocketAddress(_pSockFile->path())));
|
||||||
|
}
|
||||||
_pSocket->setBlocking(false);
|
_pSocket->setBlocking(false);
|
||||||
port = _pSocket->address().port();
|
|
||||||
return static_cast<int>(_pSocket->impl()->sockfd());
|
return static_cast<int>(_pSocket->impl()->sockfd());
|
||||||
}
|
}
|
||||||
else
|
std::unique_ptr<TemporaryFile> _pSockFile;
|
||||||
|
#else // no unix socket, listen on localhost
|
||||||
|
int eventfd()
|
||||||
{
|
{
|
||||||
delete _pSocket;
|
if (!_pSocket)
|
||||||
_pSocket = 0;
|
_pSocket.reset(new ServerSocket(SocketAddress("127.0.0.1", 0)));
|
||||||
port = 0;
|
_port = _pSocket->address().port();
|
||||||
|
_pSocket->setBlocking(false);
|
||||||
|
return static_cast<int>(_pSocket->impl()->sockfd());
|
||||||
}
|
}
|
||||||
return 0;
|
int _port = 0;
|
||||||
}
|
#endif // POCO_HAS_UNIX_SOCKET
|
||||||
|
|
||||||
|
std::unique_ptr<ServerSocket> _pSocket;
|
||||||
#endif // WEPOLL_H_
|
#endif // WEPOLL_H_
|
||||||
|
|
||||||
mutable Mutex _mutex;
|
mutable Mutex _mutex;
|
||||||
SocketMap _socketMap;
|
SocketMap _socketMap;
|
||||||
std::vector<struct epoll_event> _events;
|
std::vector<struct epoll_event> _events;
|
||||||
int _port;
|
|
||||||
std::atomic<int> _eventfd;
|
std::atomic<int> _eventfd;
|
||||||
#ifdef WEPOLL_H_
|
EPollHandle _epollfd;
|
||||||
std::atomic <HANDLE> _epollfd;
|
|
||||||
ServerSocket* _pSocket;
|
|
||||||
#else
|
|
||||||
std::atomic<int> _epollfd;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const epoll_event PollSetImpl::EPOLL_NULL_EVENT = {0, {0}};
|
||||||
|
|
||||||
#elif defined(POCO_HAVE_FD_POLL)
|
#elif defined(POCO_HAVE_FD_POLL)
|
||||||
|
|
||||||
|
@ -20,12 +20,14 @@
|
|||||||
#include "Poco/NumberParser.h"
|
#include "Poco/NumberParser.h"
|
||||||
#include "Poco/BinaryReader.h"
|
#include "Poco/BinaryReader.h"
|
||||||
#include "Poco/BinaryWriter.h"
|
#include "Poco/BinaryWriter.h"
|
||||||
|
#include "Poco/RegularExpression.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
|
||||||
using Poco::RefCountedObject;
|
using Poco::RefCountedObject;
|
||||||
using Poco::NumberParser;
|
using Poco::NumberParser;
|
||||||
|
using Poco::RegularExpression;
|
||||||
using Poco::UInt16;
|
using Poco::UInt16;
|
||||||
using Poco::InvalidArgumentException;
|
using Poco::InvalidArgumentException;
|
||||||
using Poco::Net::Impl::SocketAddressImpl;
|
using Poco::Net::Impl::SocketAddressImpl;
|
||||||
@ -33,7 +35,7 @@ using Poco::Net::Impl::IPv4SocketAddressImpl;
|
|||||||
#ifdef POCO_HAVE_IPv6
|
#ifdef POCO_HAVE_IPv6
|
||||||
using Poco::Net::Impl::IPv6SocketAddressImpl;
|
using Poco::Net::Impl::IPv6SocketAddressImpl;
|
||||||
#endif
|
#endif
|
||||||
#ifdef POCO_OS_FAMILY_UNIX
|
#ifdef POCO_HAS_UNIX_SOCKET
|
||||||
using Poco::Net::Impl::LocalSocketAddressImpl;
|
using Poco::Net::Impl::LocalSocketAddressImpl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -63,7 +65,7 @@ const SocketAddress::Family SocketAddress::IPv4;
|
|||||||
#if defined(POCO_HAVE_IPv6)
|
#if defined(POCO_HAVE_IPv6)
|
||||||
const SocketAddress::Family SocketAddress::IPv6;
|
const SocketAddress::Family SocketAddress::IPv6;
|
||||||
#endif
|
#endif
|
||||||
#if defined(POCO_OS_FAMILY_UNIX)
|
#if defined(POCO_HAS_UNIX_SOCKET)
|
||||||
const SocketAddress::Family SocketAddress::UNIX_LOCAL;
|
const SocketAddress::Family SocketAddress::UNIX_LOCAL;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@ -143,7 +145,7 @@ SocketAddress::SocketAddress(const SocketAddress& socketAddress)
|
|||||||
else if (socketAddress.family() == IPv6)
|
else if (socketAddress.family() == IPv6)
|
||||||
newIPv6(reinterpret_cast<const sockaddr_in6*>(socketAddress.addr()));
|
newIPv6(reinterpret_cast<const sockaddr_in6*>(socketAddress.addr()));
|
||||||
#endif
|
#endif
|
||||||
#if defined(POCO_OS_FAMILY_UNIX)
|
#if defined(POCO_HAS_UNIX_SOCKET)
|
||||||
else if (socketAddress.family() == UNIX_LOCAL)
|
else if (socketAddress.family() == UNIX_LOCAL)
|
||||||
newLocal(reinterpret_cast<const sockaddr_un*>(socketAddress.addr()));
|
newLocal(reinterpret_cast<const sockaddr_un*>(socketAddress.addr()));
|
||||||
#endif
|
#endif
|
||||||
@ -164,7 +166,7 @@ SocketAddress::SocketAddress(const struct sockaddr* sockAddr, poco_socklen_t len
|
|||||||
else if (length == sizeof(struct sockaddr_in6) && sockAddr->sa_family == AF_INET6)
|
else if (length == sizeof(struct sockaddr_in6) && sockAddr->sa_family == AF_INET6)
|
||||||
newIPv6(reinterpret_cast<const struct sockaddr_in6*>(sockAddr));
|
newIPv6(reinterpret_cast<const struct sockaddr_in6*>(sockAddr));
|
||||||
#endif
|
#endif
|
||||||
#if defined(POCO_OS_FAMILY_UNIX)
|
#if defined(POCO_HAS_UNIX_SOCKET)
|
||||||
else if (length > 0 && length <= sizeof(struct sockaddr_un) && sockAddr->sa_family == AF_UNIX)
|
else if (length > 0 && length <= sizeof(struct sockaddr_un) && sockAddr->sa_family == AF_UNIX)
|
||||||
newLocal(reinterpret_cast<const sockaddr_un*>(sockAddr));
|
newLocal(reinterpret_cast<const sockaddr_un*>(sockAddr));
|
||||||
#endif
|
#endif
|
||||||
@ -181,7 +183,7 @@ bool SocketAddress::operator < (const SocketAddress& socketAddress) const
|
|||||||
{
|
{
|
||||||
if (family() < socketAddress.family()) return true;
|
if (family() < socketAddress.family()) return true;
|
||||||
if (family() > socketAddress.family()) return false;
|
if (family() > socketAddress.family()) return false;
|
||||||
#if defined(POCO_OS_FAMILY_UNIX)
|
#if defined(POCO_HAS_UNIX_SOCKET)
|
||||||
if (family() == UNIX_LOCAL) return toString() < socketAddress.toString();
|
if (family() == UNIX_LOCAL) return toString() < socketAddress.toString();
|
||||||
#endif
|
#endif
|
||||||
if (host() < socketAddress.host()) return true;
|
if (host() < socketAddress.host()) return true;
|
||||||
@ -200,7 +202,7 @@ SocketAddress& SocketAddress::operator = (const SocketAddress& socketAddress)
|
|||||||
else if (socketAddress.family() == IPv6)
|
else if (socketAddress.family() == IPv6)
|
||||||
newIPv6(reinterpret_cast<const sockaddr_in6*>(socketAddress.addr()));
|
newIPv6(reinterpret_cast<const sockaddr_in6*>(socketAddress.addr()));
|
||||||
#endif
|
#endif
|
||||||
#if defined(POCO_OS_FAMILY_UNIX)
|
#if defined(POCO_HAS_UNIX_SOCKET)
|
||||||
else if (socketAddress.family() == UNIX_LOCAL)
|
else if (socketAddress.family() == UNIX_LOCAL)
|
||||||
newLocal(reinterpret_cast<const sockaddr_un*>(socketAddress.addr()));
|
newLocal(reinterpret_cast<const sockaddr_un*>(socketAddress.addr()));
|
||||||
#endif
|
#endif
|
||||||
@ -325,7 +327,7 @@ void SocketAddress::init(Family fam, const std::string& hostAddress, Poco::UInt1
|
|||||||
|
|
||||||
void SocketAddress::init(Family fam, const std::string& address)
|
void SocketAddress::init(Family fam, const std::string& address)
|
||||||
{
|
{
|
||||||
#if defined(POCO_OS_FAMILY_UNIX)
|
#if defined(POCO_HAS_UNIX_SOCKET)
|
||||||
if (fam == UNIX_LOCAL)
|
if (fam == UNIX_LOCAL)
|
||||||
{
|
{
|
||||||
newLocal(address);
|
newLocal(address);
|
||||||
@ -364,6 +366,15 @@ void SocketAddress::init(const std::string& hostAndPort)
|
|||||||
{
|
{
|
||||||
poco_assert (!hostAndPort.empty());
|
poco_assert (!hostAndPort.empty());
|
||||||
|
|
||||||
|
#if defined(POCO_OS_FAMILY_WINDOWS) && defined(POCO_HAS_UNIX_SOCKET)
|
||||||
|
RegularExpression re(R"((?:[a-zA-Z]\:|\\\\[\w\s\.]+\\[\w\s\.$]+)\\(?:[\w\s\.]+\\)*[\w\s\.]*?$)");
|
||||||
|
if (re.match(hostAndPort))
|
||||||
|
{
|
||||||
|
newLocal(hostAndPort);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
std::string host;
|
std::string host;
|
||||||
std::string port;
|
std::string port;
|
||||||
std::string::const_iterator it = hostAndPort.begin();
|
std::string::const_iterator it = hostAndPort.begin();
|
||||||
|
@ -127,7 +127,7 @@ std::string IPv6SocketAddressImpl::toString() const
|
|||||||
#endif // POCO_HAVE_IPv6
|
#endif // POCO_HAVE_IPv6
|
||||||
|
|
||||||
|
|
||||||
#if defined(POCO_OS_FAMILY_UNIX)
|
#if defined(POCO_HAS_UNIX_SOCKET)
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -146,22 +146,36 @@ LocalSocketAddressImpl::LocalSocketAddressImpl(const char* path)
|
|||||||
{
|
{
|
||||||
poco_assert (std::strlen(path) < sizeof(_pAddr->sun_path));
|
poco_assert (std::strlen(path) < sizeof(_pAddr->sun_path));
|
||||||
|
|
||||||
|
#if POCO_OS != POCO_OS_LINUX
|
||||||
|
if (path[0] == 0)
|
||||||
|
throw Poco::InvalidArgumentException("LocalSocketAddressImpl(): "
|
||||||
|
"abstract sockets are only supported on Linux");
|
||||||
|
#endif
|
||||||
|
|
||||||
_pAddr = new sockaddr_un;
|
_pAddr = new sockaddr_un;
|
||||||
poco_set_sun_len(_pAddr, std::strlen(path) + sizeof(struct sockaddr_un) - sizeof(_pAddr->sun_path) + 1);
|
std::memset(_pAddr, 0, sizeof(sockaddr_un));
|
||||||
|
std::size_t length = strlen(path);
|
||||||
|
poco_set_sun_len(_pAddr, length + sizeof(struct sockaddr_un) - sizeof(_pAddr->sun_path) + 1);
|
||||||
_pAddr->sun_family = AF_UNIX;
|
_pAddr->sun_family = AF_UNIX;
|
||||||
std::strcpy(_pAddr->sun_path, path);
|
std::memcpy(&_pAddr->sun_path, path, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LocalSocketAddressImpl::LocalSocketAddressImpl(const char* path, std::size_t length)
|
LocalSocketAddressImpl::LocalSocketAddressImpl(const char* path, std::size_t length)
|
||||||
{
|
{
|
||||||
poco_assert (length < sizeof(_pAddr->sun_path));
|
poco_assert (length && length < sizeof(_pAddr->sun_path));
|
||||||
|
|
||||||
|
#if POCO_OS != POCO_OS_LINUX
|
||||||
|
if (path[0] == 0)
|
||||||
|
throw Poco::InvalidArgumentException("LocalSocketAddressImpl(): "
|
||||||
|
"abstract sockets are only supported on Linux");
|
||||||
|
#endif
|
||||||
|
|
||||||
_pAddr = new sockaddr_un;
|
_pAddr = new sockaddr_un;
|
||||||
|
std::memset(_pAddr, 0, sizeof(sockaddr_un));
|
||||||
poco_set_sun_len(_pAddr, length + sizeof(struct sockaddr_un) - sizeof(_pAddr->sun_path) + 1);
|
poco_set_sun_len(_pAddr, length + sizeof(struct sockaddr_un) - sizeof(_pAddr->sun_path) + 1);
|
||||||
_pAddr->sun_family = AF_UNIX;
|
_pAddr->sun_family = AF_UNIX;
|
||||||
std::memcpy(_pAddr->sun_path, path, length);
|
std::memcpy(&_pAddr->sun_path, path, length);
|
||||||
_pAddr->sun_path[length] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -178,7 +192,7 @@ std::string LocalSocketAddressImpl::toString() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // POCO_OS_FAMILY_UNIX
|
#endif // POCO_HAS_UNIX_SOCKET
|
||||||
|
|
||||||
|
|
||||||
} } } // namespace Poco::Net::Impl
|
} } } // namespace Poco::Net::Impl
|
||||||
|
@ -227,8 +227,15 @@ void SocketImpl::bind(const SocketAddress& address, bool reuseAddress, bool reus
|
|||||||
{
|
{
|
||||||
init(address.af());
|
init(address.af());
|
||||||
}
|
}
|
||||||
setReuseAddress(reuseAddress);
|
|
||||||
setReusePort(reusePort);
|
#ifdef POCO_HAS_UNIX_SOCKET
|
||||||
|
if (address.family() != SocketAddress::Family::UNIX_LOCAL)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
setReuseAddress(reuseAddress);
|
||||||
|
setReusePort(reusePort);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(POCO_VXWORKS)
|
#if defined(POCO_VXWORKS)
|
||||||
int rc = ::bind(_sockfd, (sockaddr*) address.addr(), address.length());
|
int rc = ::bind(_sockfd, (sockaddr*) address.addr(), address.length());
|
||||||
#else
|
#else
|
||||||
|
@ -34,7 +34,7 @@ StreamSocketImpl::StreamSocketImpl(SocketAddress::Family family)
|
|||||||
else if (family == SocketAddress::IPv6)
|
else if (family == SocketAddress::IPv6)
|
||||||
init(AF_INET6);
|
init(AF_INET6);
|
||||||
#endif
|
#endif
|
||||||
#if defined(POCO_OS_FAMILY_UNIX)
|
#if defined(POCO_HAS_UNIX_SOCKET)
|
||||||
else if (family == SocketAddress::UNIX_LOCAL)
|
else if (family == SocketAddress::UNIX_LOCAL)
|
||||||
init(AF_UNIX);
|
init(AF_UNIX);
|
||||||
#endif
|
#endif
|
||||||
|
@ -139,7 +139,7 @@ void TCPServer::run()
|
|||||||
if (!_pConnectionFilter || _pConnectionFilter->accept(ss))
|
if (!_pConnectionFilter || _pConnectionFilter->accept(ss))
|
||||||
{
|
{
|
||||||
// enable nodelay per default: OSX really needs that
|
// enable nodelay per default: OSX really needs that
|
||||||
#if defined(POCO_OS_FAMILY_UNIX)
|
#if defined(POCO_HAS_UNIX_SOCKET)
|
||||||
if (ss.address().family() != AddressFamily::UNIX_LOCAL)
|
if (ss.address().family() != AddressFamily::UNIX_LOCAL)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
@ -11,7 +11,9 @@
|
|||||||
// SPDX-License-Identifier: BSL-1.0
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#ifndef NOMINMAX
|
||||||
|
#define NOMINMAX
|
||||||
|
#endif // NOMINMAX
|
||||||
#include "Poco/Net/WebSocketImpl.h"
|
#include "Poco/Net/WebSocketImpl.h"
|
||||||
#include "Poco/Net/NetException.h"
|
#include "Poco/Net/NetException.h"
|
||||||
#include "Poco/Net/WebSocket.h"
|
#include "Poco/Net/WebSocket.h"
|
||||||
|
@ -72,6 +72,11 @@ void EchoServer::run()
|
|||||||
{
|
{
|
||||||
ss.sendBytes(buffer, n);
|
ss.sendBytes(buffer, n);
|
||||||
n = ss.receiveBytes(buffer, sizeof(buffer));
|
n = ss.receiveBytes(buffer, sizeof(buffer));
|
||||||
|
if (n == 0)
|
||||||
|
{
|
||||||
|
_stop = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Poco::Exception& exc)
|
catch (Poco::Exception& exc)
|
||||||
|
@ -326,10 +326,9 @@ void PollSetTest::testPoll()
|
|||||||
|
|
||||||
void PollSetTest::testPollNoServer()
|
void PollSetTest::testPollNoServer()
|
||||||
{
|
{
|
||||||
StreamSocket ss1;
|
StreamSocket ss1(SocketAddress::IPv4);
|
||||||
StreamSocket ss2;
|
StreamSocket ss2(SocketAddress::IPv4);
|
||||||
ss1.connectNB(SocketAddress("127.0.0.1", 0xFEFE));
|
|
||||||
ss2.connectNB(SocketAddress("127.0.0.1", 0xFEFF));
|
|
||||||
PollSet ps;
|
PollSet ps;
|
||||||
assertTrue(ps.empty());
|
assertTrue(ps.empty());
|
||||||
ps.add(ss1, PollSet::POLL_READ | PollSet::POLL_WRITE | PollSet::POLL_ERROR);
|
ps.add(ss1, PollSet::POLL_READ | PollSet::POLL_WRITE | PollSet::POLL_ERROR);
|
||||||
@ -337,26 +336,35 @@ void PollSetTest::testPollNoServer()
|
|||||||
assertTrue(!ps.empty());
|
assertTrue(!ps.empty());
|
||||||
assertTrue(ps.has(ss1));
|
assertTrue(ps.has(ss1));
|
||||||
assertTrue(ps.has(ss2));
|
assertTrue(ps.has(ss2));
|
||||||
|
|
||||||
|
// should be like this, but Linux epoll disagrees ...
|
||||||
|
//assertEqual(0, static_cast<int>(ps.poll(Timespan(100)).size()));
|
||||||
|
|
||||||
|
ss1.connectNB(SocketAddress("127.0.0.1", 0xFEFE));
|
||||||
|
ss2.connectNB(SocketAddress("127.0.0.1", 0xFEFF));
|
||||||
|
|
||||||
PollSet::SocketModeMap sm;
|
PollSet::SocketModeMap sm;
|
||||||
int signalled = 0;
|
int signalledErrors = 0;
|
||||||
Stopwatch sw; sw.start();
|
Stopwatch sw; sw.start();
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
sm = ps.poll(Timespan(1000000));
|
sm = ps.poll(Timespan(1000000));
|
||||||
for (auto s : sm)
|
for (auto s : sm)
|
||||||
|
{
|
||||||
assertTrue(0 != (s.second & PollSet::POLL_ERROR));
|
assertTrue(0 != (s.second & PollSet::POLL_ERROR));
|
||||||
|
++signalledErrors;
|
||||||
|
}
|
||||||
|
|
||||||
signalled += static_cast<int>(sm.size());
|
|
||||||
sm.clear();
|
sm.clear();
|
||||||
int secs = sw.elapsedSeconds();
|
int secs = sw.elapsedSeconds();
|
||||||
if (secs > 10)
|
if (secs > 10)
|
||||||
{
|
{
|
||||||
fail(Poco::format("testPollNoServer() timed out after %ds, "
|
fail(Poco::format("testPollNoServer() timed out after %ds, "
|
||||||
"sockets signalled=%d (expected 2)",
|
"sockets signalled=%d (expected 2)",
|
||||||
secs, signalled), __LINE__);
|
secs, signalledErrors), __LINE__);
|
||||||
}
|
}
|
||||||
} while (signalled < 2);
|
} while (signalledErrors < 2);
|
||||||
assertTrue(signalled == 2);
|
assertEqual(2, signalledErrors);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,11 +373,9 @@ void PollSetTest::testPollClosedServer()
|
|||||||
{
|
{
|
||||||
EchoServer echoServer1;
|
EchoServer echoServer1;
|
||||||
EchoServer echoServer2;
|
EchoServer echoServer2;
|
||||||
StreamSocket ss1;
|
|
||||||
StreamSocket ss2;
|
|
||||||
|
|
||||||
ss1.connect(SocketAddress("127.0.0.1", echoServer1.port()));
|
StreamSocket ss1(SocketAddress::IPv4);
|
||||||
ss2.connect(SocketAddress("127.0.0.1", echoServer2.port()));
|
StreamSocket ss2(SocketAddress::IPv4);
|
||||||
|
|
||||||
PollSet ps;
|
PollSet ps;
|
||||||
assertTrue(ps.empty());
|
assertTrue(ps.empty());
|
||||||
@ -379,6 +385,11 @@ void PollSetTest::testPollClosedServer()
|
|||||||
assertTrue(ps.has(ss1));
|
assertTrue(ps.has(ss1));
|
||||||
assertTrue(ps.has(ss2));
|
assertTrue(ps.has(ss2));
|
||||||
|
|
||||||
|
//assertEqual(0, static_cast<int>(ps.poll(Timespan(100)).size()));
|
||||||
|
|
||||||
|
ss1.connect(SocketAddress("127.0.0.1", echoServer1.port()));
|
||||||
|
ss2.connect(SocketAddress("127.0.0.1", echoServer2.port()));
|
||||||
|
|
||||||
std::string str = "HELLO";
|
std::string str = "HELLO";
|
||||||
int len = static_cast<int>(str.length());
|
int len = static_cast<int>(str.length());
|
||||||
|
|
||||||
@ -393,14 +404,23 @@ void PollSetTest::testPollClosedServer()
|
|||||||
int secs = sw.elapsedSeconds();
|
int secs = sw.elapsedSeconds();
|
||||||
if (secs > 10)
|
if (secs > 10)
|
||||||
{
|
{
|
||||||
fail(Poco::format("testPollClosedServer() timed out "
|
fail(Poco::format("testPollClosedServer(1) timed out "
|
||||||
"waiting on server after %ds", secs), __LINE__);
|
"waiting on server after %ds", secs), __LINE__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
echoServer2.stop();
|
echoServer2.stop();
|
||||||
assertTrue (len == ss2.sendBytes(str.data(), len));
|
assertTrue (len == ss2.sendBytes(str.data(), len));
|
||||||
while (!echoServer2.done()) Thread::sleep(10);
|
while (!echoServer2.done())
|
||||||
|
{
|
||||||
|
Thread::sleep(10);
|
||||||
|
int secs = sw.elapsedSeconds();
|
||||||
|
if (secs > 10)
|
||||||
|
{
|
||||||
|
fail(Poco::format("testPollClosedServer(2) timed out "
|
||||||
|
"waiting on server after %ds", secs), __LINE__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int signalled = 0;
|
int signalled = 0;
|
||||||
sw.restart();
|
sw.restart();
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "SocketAddressTest.h"
|
#include "SocketAddressTest.h"
|
||||||
#include "CppUnit/TestCaller.h"
|
#include "CppUnit/TestCaller.h"
|
||||||
#include "CppUnit/TestSuite.h"
|
#include "CppUnit/TestSuite.h"
|
||||||
|
#include "Poco/Path.h"
|
||||||
#include "Poco/Net/SocketAddress.h"
|
#include "Poco/Net/SocketAddress.h"
|
||||||
#include "Poco/Net/NetException.h"
|
#include "Poco/Net/NetException.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -23,6 +24,7 @@ using Poco::Net::HostNotFoundException;
|
|||||||
using Poco::Net::ServiceNotFoundException;
|
using Poco::Net::ServiceNotFoundException;
|
||||||
using Poco::Net::NoAddressFoundException;
|
using Poco::Net::NoAddressFoundException;
|
||||||
using Poco::Net::AddressFamilyMismatchException;
|
using Poco::Net::AddressFamilyMismatchException;
|
||||||
|
using Poco::Path;
|
||||||
using Poco::InvalidArgumentException;
|
using Poco::InvalidArgumentException;
|
||||||
|
|
||||||
|
|
||||||
@ -184,25 +186,27 @@ void SocketAddressTest::testSocketAddress6()
|
|||||||
|
|
||||||
void SocketAddressTest::testSocketAddressUnixLocal()
|
void SocketAddressTest::testSocketAddressUnixLocal()
|
||||||
{
|
{
|
||||||
#ifdef POCO_OS_FAMILY_UNIX
|
#ifdef POCO_HAS_UNIX_SOCKET
|
||||||
SocketAddress sa1(SocketAddress::UNIX_LOCAL, "/tmp/sock1");
|
std::string name1 = Path::tempHome() + "sock1";
|
||||||
|
SocketAddress sa1(SocketAddress::UNIX_LOCAL, name1);
|
||||||
assertTrue (sa1.af() == AF_UNIX);
|
assertTrue (sa1.af() == AF_UNIX);
|
||||||
assertTrue (sa1.family() == SocketAddress::UNIX_LOCAL);
|
assertTrue (sa1.family() == SocketAddress::UNIX_LOCAL);
|
||||||
assertTrue (sa1.toString() == "/tmp/sock1");
|
assertTrue (sa1.toString() == name1);
|
||||||
|
|
||||||
SocketAddress sa2(SocketAddress::UNIX_LOCAL, "/tmp/sock2");
|
std::string name2 = Path::tempHome() + "sock2";
|
||||||
|
SocketAddress sa2(SocketAddress::UNIX_LOCAL, name2);
|
||||||
assertTrue (sa1 != sa2);
|
assertTrue (sa1 != sa2);
|
||||||
assertTrue (sa1 < sa2);
|
assertTrue (sa1 < sa2);
|
||||||
|
|
||||||
SocketAddress sa3(SocketAddress::UNIX_LOCAL, "/tmp/sock1");
|
SocketAddress sa3(SocketAddress::UNIX_LOCAL, name1);
|
||||||
assertTrue (sa1 == sa3);
|
assertTrue (sa1 == sa3);
|
||||||
assertTrue (!(sa1 < sa3));
|
assertTrue (!(sa1 < sa3));
|
||||||
|
|
||||||
SocketAddress sa4("/tmp/sock1");
|
SocketAddress sa4(name1);
|
||||||
assertTrue (sa1 == sa4);
|
assertTrue (sa1 == sa4);
|
||||||
assertTrue (sa4.toString() == "/tmp/sock1");
|
assertTrue (sa4.toString() == name1);
|
||||||
#else
|
#else
|
||||||
std::cout << "[UNIX LOCAL DISABLED]" << std::endl;
|
std::cout << "[UNIX LOCAL SOCKET DISABLED]" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "Poco/FIFOBuffer.h"
|
#include "Poco/FIFOBuffer.h"
|
||||||
#include "Poco/Delegate.h"
|
#include "Poco/Delegate.h"
|
||||||
#include "Poco/File.h"
|
#include "Poco/File.h"
|
||||||
|
#include "Poco/Path.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
@ -36,6 +37,8 @@ using Poco::TimeoutException;
|
|||||||
using Poco::InvalidArgumentException;
|
using Poco::InvalidArgumentException;
|
||||||
using Poco::Buffer;
|
using Poco::Buffer;
|
||||||
using Poco::FIFOBuffer;
|
using Poco::FIFOBuffer;
|
||||||
|
using Poco::Path;
|
||||||
|
using Poco::File;
|
||||||
using Poco::delegate;
|
using Poco::delegate;
|
||||||
|
|
||||||
|
|
||||||
@ -536,12 +539,14 @@ void SocketTest::testSelect3()
|
|||||||
|
|
||||||
void SocketTest::testEchoUnixLocal()
|
void SocketTest::testEchoUnixLocal()
|
||||||
{
|
{
|
||||||
#if defined(POCO_OS_FAMILY_UNIX)
|
#if defined(POCO_HAS_UNIX_SOCKET)
|
||||||
#if POCO_OS == POCO_OS_ANDROID
|
#if POCO_OS == POCO_OS_ANDROID
|
||||||
Poco::File socketFile("/data/local/tmp/SocketTest.sock");
|
File socketFile("/data/local/tmp/SocketTest.sock");
|
||||||
|
#elif defined(POCO_OS_FAMILY_WINDOWS)
|
||||||
|
File socketFile(Path::tempHome() + "SocketTest.sock");
|
||||||
#else
|
#else
|
||||||
Poco::File socketFile("/tmp/SocketTest.sock");
|
File socketFile("/tmp/SocketTest.sock");
|
||||||
#endif
|
#endif // POCO_OS == POCO_OS_ANDROID
|
||||||
if (socketFile.exists()) socketFile.remove();
|
if (socketFile.exists()) socketFile.remove();
|
||||||
SocketAddress localAddr(SocketAddress::UNIX_LOCAL, socketFile.path());
|
SocketAddress localAddr(SocketAddress::UNIX_LOCAL, socketFile.path());
|
||||||
EchoServer echoServer(localAddr);
|
EchoServer echoServer(localAddr);
|
||||||
@ -554,7 +559,37 @@ void SocketTest::testEchoUnixLocal()
|
|||||||
assertTrue (n == 5);
|
assertTrue (n == 5);
|
||||||
assertTrue (std::string(buffer, n) == "hello");
|
assertTrue (std::string(buffer, n) == "hello");
|
||||||
ss.close();
|
ss.close();
|
||||||
socketFile.remove();
|
if (socketFile.exists()) socketFile.remove();
|
||||||
|
echoServer.stop();
|
||||||
|
#else // POCO_HAS_UNIX_SOCKET
|
||||||
|
#pragma message("[UNIX LOCAL SOCKET DISABLED]")
|
||||||
|
std::cout << "[UNIX LOCAL SOCKET DISABLED]" << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SocketTest::testUnixLocalAbstract()
|
||||||
|
{
|
||||||
|
// abstract local sockets don't work on windows
|
||||||
|
// see https://github.com/microsoft/WSL/issues/4240
|
||||||
|
// they are a nonportable Linux extension
|
||||||
|
#if (POCO_OS == POCO_OS_LINUX) && defined(POCO_HAS_UNIX_SOCKET)
|
||||||
|
std::string addr("\0look ma - no file!", 20);
|
||||||
|
SocketAddress localAddr(SocketAddress::UNIX_LOCAL, addr);
|
||||||
|
EchoServer echoServer(localAddr);
|
||||||
|
StreamSocket ss(SocketAddress::UNIX_LOCAL);
|
||||||
|
ss.connect(localAddr);
|
||||||
|
int n = ss.sendBytes("hello", 5);
|
||||||
|
assertTrue(n == 5);
|
||||||
|
char buffer[256];
|
||||||
|
n = ss.receiveBytes(buffer, sizeof(buffer));
|
||||||
|
assertTrue(n == 5);
|
||||||
|
assertTrue(std::string(buffer, n) == "hello");
|
||||||
|
ss.close();
|
||||||
|
echoServer.stop();
|
||||||
|
#else // POCO_HAS_UNIX_SOCKET
|
||||||
|
#pragma message("[ABSTRACT UNIX LOCAL SOCKET DISABLED]")
|
||||||
|
std::cout << "[ABSTRACT UNIX LOCAL SOCKET DISABLED]" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -610,6 +645,7 @@ CppUnit::Test* SocketTest::suite()
|
|||||||
CppUnit_addTest(pSuite, SocketTest, testSelect2);
|
CppUnit_addTest(pSuite, SocketTest, testSelect2);
|
||||||
CppUnit_addTest(pSuite, SocketTest, testSelect3);
|
CppUnit_addTest(pSuite, SocketTest, testSelect3);
|
||||||
CppUnit_addTest(pSuite, SocketTest, testEchoUnixLocal);
|
CppUnit_addTest(pSuite, SocketTest, testEchoUnixLocal);
|
||||||
|
CppUnit_addTest(pSuite, SocketTest, testUnixLocalAbstract);
|
||||||
|
|
||||||
return pSuite;
|
return pSuite;
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,7 @@ public:
|
|||||||
void testSelect2();
|
void testSelect2();
|
||||||
void testSelect3();
|
void testSelect3();
|
||||||
void testEchoUnixLocal();
|
void testEchoUnixLocal();
|
||||||
|
void testUnixLocalAbstract();
|
||||||
|
|
||||||
void setUp();
|
void setUp();
|
||||||
void tearDown();
|
void tearDown();
|
||||||
|
Loading…
Reference in New Issue
Block a user