summaryrefslogtreecommitdiff
path: root/Userland/Services/EchoServer/Client.cpp
blob: 0a3ae489ba1944dea0cc403e876879ce88cd4226 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/*
 * Copyright (c) 2020, the SerenityOS developers.
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include "Client.h"
#include "LibCore/EventLoop.h"

Client::Client(int id, NonnullOwnPtr<Core::Stream::TCPSocket> socket)
    : m_id(id)
    , m_socket(move(socket))
{
    m_socket->on_ready_to_read = [this] {
        if (m_socket->is_eof())
            return;

        auto result = drain_socket();
        if (result.is_error()) {
            dbgln("Failed while trying to drain the socket: {}", result.error());
            Core::deferred_invoke([this, strong_this = NonnullRefPtr(*this)] { quit(); });
        }
    };
}

ErrorOr<void> Client::drain_socket()
{
    NonnullRefPtr<Client> protect(*this);

    auto buffer = TRY(ByteBuffer::create_uninitialized(1024));

    while (TRY(m_socket->can_read_without_blocking())) {
        auto nread = TRY(m_socket->read(buffer));

        dbgln("Read {} bytes.", nread);

        if (m_socket->is_eof()) {
            Core::deferred_invoke([this, strong_this = NonnullRefPtr(*this)] { quit(); });
            break;
        }

        TRY(m_socket->write({ buffer.data(), nread }));
    }

    return {};
}

void Client::quit()
{
    m_socket->close();
    if (on_exit)
        on_exit();
}