LibCore: Fix UDPServer up to properly receive data

Prior to this, UDPServer was using listen/accept, which does not make
sense in the context of UDP.
This commit is contained in:
AnotherTest 2020-04-04 14:29:33 +04:30 committed by Andreas Kling
parent 2ea934bcfd
commit d8e944e899
Notes: sideshowbarker 2024-07-19 07:57:26 +09:00
2 changed files with 27 additions and 26 deletions

View file

@ -30,7 +30,6 @@
#include <LibCore/UDPServer.h>
#include <LibCore/UDPSocket.h>
#include <stdio.h>
#include <sys/socket.h>
namespace Core {
@ -45,41 +44,36 @@ UDPServer::~UDPServer()
{
}
bool UDPServer::listen(const IPv4Address& address, u16 port)
bool UDPServer::bind(const IPv4Address& address, u16 port)
{
if (m_listening)
if (m_bound)
return false;
int rc;
auto socket_address = SocketAddress(address, port);
auto in = socket_address.to_sockaddr_in();
auto saddr = SocketAddress(address, port);
auto in = saddr.to_sockaddr_in();
rc = ::bind(m_fd, (const sockaddr*)&in, sizeof(in));
ASSERT(rc == 0);
rc = ::listen(m_fd, 5);
ASSERT(rc == 0);
m_listening = true;
m_notifier = Notifier::construct(m_fd, Notifier::Event::Read, this);
m_notifier->on_ready_to_read = [this] {
if (on_ready_to_accept)
on_ready_to_accept();
if (on_ready_to_receive)
on_ready_to_receive();
};
return true;
}
RefPtr<UDPSocket> UDPServer::accept()
ByteBuffer UDPServer::receive(size_t size, sockaddr_in& in)
{
ASSERT(m_listening);
sockaddr_in in;
socklen_t in_size = sizeof(in);
int accepted_fd = ::accept(m_fd, (sockaddr*)&in, &in_size);
if (accepted_fd < 0) {
perror("accept");
return nullptr;
auto buf = ByteBuffer::create_zeroed(size);
socklen_t in_len = sizeof(in);
ssize_t rlen = ::recvfrom(m_fd, buf.data(), size, 0, (sockaddr*)&in, &in_len);
if (rlen < 0) {
dbg() << "recvfrom: " << strerror(errno);
return {};
}
return UDPSocket::construct(accepted_fd);
return buf;
}
Optional<IPv4Address> UDPServer::local_address() const

View file

@ -26,10 +26,12 @@
#pragma once
#include <AK/ByteBuffer.h>
#include <AK/Forward.h>
#include <AK/Function.h>
#include <LibCore/Forward.h>
#include <LibCore/Object.h>
#include <LibCore/SocketAddress.h>
namespace Core {
@ -38,21 +40,26 @@ class UDPServer : public Object {
public:
virtual ~UDPServer() override;
bool is_listening() const { return m_listening; }
bool listen(const IPv4Address& address, u16 port);
bool is_bound() const { return m_bound; }
RefPtr<UDPSocket> accept();
bool bind(const IPv4Address& address, u16 port);
ByteBuffer receive(size_t size, sockaddr_in& from);
ByteBuffer receive(size_t size)
{
struct sockaddr_in saddr;
return receive(size, saddr);
};
Optional<IPv4Address> local_address() const;
Optional<u16> local_port() const;
Function<void()> on_ready_to_accept;
Function<void()> on_ready_to_receive;
private:
explicit UDPServer(Object* parent = nullptr);
int m_fd { -1 };
bool m_listening { false };
bool m_bound { false };
RefPtr<Notifier> m_notifier;
};