1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 16:57:35 +00:00

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
2 changed files with 27 additions and 26 deletions

View file

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

View file

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