diff options
author | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-20 14:33:09 +1000 |
---|---|---|
committer | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-20 14:33:09 +1000 |
commit | 6352e8e3196f78388b6c771073f9e03eaa612673 (patch) | |
tree | e23772f79a7fbc41bc9108951e9e136857484bf4 /source/core/StarUdp.cpp | |
parent | 6741a057e5639280d85d0f88ba26f000baa58f61 (diff) |
everything everywhere
all at once
Diffstat (limited to 'source/core/StarUdp.cpp')
-rw-r--r-- | source/core/StarUdp.cpp | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/source/core/StarUdp.cpp b/source/core/StarUdp.cpp new file mode 100644 index 0000000..9ff7b48 --- /dev/null +++ b/source/core/StarUdp.cpp @@ -0,0 +1,84 @@ +#include "StarUdp.hpp" +#include "StarLogging.hpp" +#include "StarNetImpl.hpp" + +namespace Star { + +UdpSocket::UdpSocket(NetworkMode networkMode) : Socket(SocketType::Udp, networkMode) {} + +size_t UdpSocket::receive(HostAddressWithPort* address, char* data, size_t datasize) { + ReadLocker locker(m_mutex); + checkOpen("UdpSocket::receive"); + + int flags = 0; + int len; + struct sockaddr_storage sockAddr; + socklen_t sockAddrLen = sizeof(sockAddr); + + len = ::recvfrom(m_impl->socketDesc, data, datasize, flags, (struct sockaddr*)&sockAddr, &sockAddrLen); + + if (len < 0) { + if (!isActive()) + throw SocketClosedException("Connection closed"); + else if (netErrorInterrupt()) + len = 0; + else + throw NetworkException(strf("udp recv error: %s", netErrorString())); + } + + if (address) + setAddressFromNative(*address, m_localAddress.address().mode(), &sockAddr); + + return len; +} + +size_t UdpSocket::send(HostAddressWithPort const& address, char const* data, size_t size) { + ReadLocker locker(m_mutex); + checkOpen("UdpSocket::send"); + + struct sockaddr_storage sockAddr; + socklen_t sockAddrLen; + setNativeFromAddress(address, &sockAddr, &sockAddrLen); + + int len = ::sendto(m_impl->socketDesc, data, size, 0, (struct sockaddr*)&sockAddr, sockAddrLen); + if (len < 0) { + if (!isActive()) + throw SocketClosedException("Connection closed"); + else if (netErrorInterrupt()) + len = 0; + else + throw NetworkException(strf("udp send error: %s", netErrorString())); + } + + return len; +} + +UdpServer::UdpServer(HostAddressWithPort const& address) + : m_hostAddress(address), m_listenSocket(make_shared<UdpSocket>(m_hostAddress.address().mode())) { + m_listenSocket->setNonBlocking(true); + m_listenSocket->bind(m_hostAddress); + Logger::debug("UdpServer listening on: %s", m_hostAddress); +} + +UdpServer::~UdpServer() { + close(); +} + +size_t UdpServer::receive(HostAddressWithPort* address, char* data, size_t bufsize, unsigned timeout) { + Socket::poll({{m_listenSocket, {true, false}}}, timeout); + return m_listenSocket->receive(address, data, bufsize); +} + +size_t UdpServer::send(HostAddressWithPort const& address, char const* data, size_t len) { + return m_listenSocket->send(address, data, len); +} + +void UdpServer::close() { + m_listenSocket->close(); +} + +bool UdpServer::isListening() const { + return m_listenSocket->isActive(); +} + +} |