sniper00 / asio-kcp

Use kcp with asio and modern C++, support async_accept, async_connect, async_read, async_read_some and can use with asio coroutine.
MIT License
31 stars 5 forks source link

kcp socket调用async_read_some时回调函数(std::function)为空指针 #5

Open quqiOnfree opened 5 hours ago

quqiOnfree commented 5 hours ago

示例 server.cpp

#include <iostream>
#include <memory>

#include "kcp.hpp"

constexpr uint8_t connect_key[32] = { 49, 194, 61, 231, 161, 216, 31, 60, 230, 26, 13, 25, 211, 185, 93, 67, 118, 28, 49, 220, 184, 71, 20, 228, 4, 24, 36, 205, 222, 99, 240, 152 };

constexpr size_t buffer_size = 8192;

std::string magic = std::string{(char*)connect_key, 32};

int main() {
    asio::io_context io_context;

    asio::signal_set signals(io_context, SIGINT, SIGTERM);
    signals.async_wait([&](auto, auto) { io_context.stop(); });

    std::string string_buffer;
    string_buffer.resize(2048);

    moon::kcp::acceptor acceptor(io_context.get_executor(), asio::ip::udp::endpoint(asio::ip::udp::v4(), 50000), magic);
    acceptor.async_accept([&](moon::kcp::connection_ptr socket){
        socket->async_write(asio::buffer("hello!"), [&](const std::error_code&, size_t size){return;});
        socket->async_read_some(asio::buffer(string_buffer), [&](const std::error_code& ec, size_t size){ // <-- 这里调用完async_read_some就会报空指针错误,如果不调用async_read_some就没事
            std::cout << std::string_view{string_buffer.begin(), string_buffer.begin() + size} << '\n';
            std::error_code ignore_ec;
            socket->close(ignore_ec);
        });
    });

    io_context.run();

    return 0;
}

client.cpp

#include <iostream>
#include <memory>

#include "kcp.hpp"

constexpr uint8_t connect_key[32] = { 49, 194, 61, 231, 161, 216, 31, 60, 230, 26, 13, 25, 211, 185, 93, 67, 118, 28, 49, 220, 184, 71, 20, 228, 4, 24, 36, 205, 222, 99, 240, 152 };

constexpr size_t buffer_size = 8192;

std::string magic = std::string{(char*)connect_key, 32};

asio::awaitable<void> start_kcp_client(asio::io_context& io_context) {
    auto [ec, socket] = co_await moon::kcp::async_connect(io_context.get_executor(), asio::ip::udp::endpoint(asio::ip::address::from_string("127.0.0.1"), 50000), magic);
    std::string string_buffer;
    string_buffer.resize(8192);
    co_await socket->async_write(asio::buffer("hello"), asio::use_awaitable);
    for (;;) {
        co_await socket->async_read_some(asio::buffer(string_buffer), asio::use_awaitable);
        std::cout << string_buffer << '\n';
    }
    co_return;
}

int main() {
    asio::io_context io_context;

    asio::signal_set signals(io_context, SIGINT, SIGTERM);
    signals.async_wait([&](auto, auto) { io_context.stop(); });

    asio::co_spawn(io_context, start_kcp_client(io_context), asio::detached);
    io_context.run();

    return 0;
}

问题: 我在调用这两个示例的时候,server.cpp中报错

Exception has occurred: W32/0xC0000005
Unhandled exception thrown: read access violation.
_Impl-> was nullptr.

image

sniper00 commented 3 hours ago

示例 server.cpp

#include <iostream>
#include <memory>

#include "kcp.hpp"

constexpr uint8_t connect_key[32] = { 49, 194, 61, 231, 161, 216, 31, 60, 230, 26, 13, 25, 211, 185, 93, 67, 118, 28, 49, 220, 184, 71, 20, 228, 4, 24, 36, 205, 222, 99, 240, 152 };

constexpr size_t buffer_size = 8192;

std::string magic = std::string{(char*)connect_key, 32};

int main() {
    asio::io_context io_context;

    asio::signal_set signals(io_context, SIGINT, SIGTERM);
    signals.async_wait([&](auto, auto) { io_context.stop(); });

    std::string string_buffer;
    string_buffer.resize(2048);

    moon::kcp::acceptor acceptor(io_context.get_executor(), asio::ip::udp::endpoint(asio::ip::udp::v4(), 50000), magic);
    acceptor.async_accept([&](moon::kcp::connection_ptr socket){
        socket->async_write(asio::buffer("hello!"), [&](const std::error_code&, size_t size){return;});
        socket->async_read_some(asio::buffer(string_buffer), [&](const std::error_code& ec, size_t size){ // <-- 这里调用完async_read_some就会报空指针错误,如果不调用async_read_some就没事
            std::cout << std::string_view{string_buffer.begin(), string_buffer.begin() + size} << '\n';
            std::error_code ignore_ec;
            socket->close(ignore_ec);
        });
    });

    io_context.run();

    return 0;
}

client.cpp

#include <iostream>
#include <memory>

#include "kcp.hpp"

constexpr uint8_t connect_key[32] = { 49, 194, 61, 231, 161, 216, 31, 60, 230, 26, 13, 25, 211, 185, 93, 67, 118, 28, 49, 220, 184, 71, 20, 228, 4, 24, 36, 205, 222, 99, 240, 152 };

constexpr size_t buffer_size = 8192;

std::string magic = std::string{(char*)connect_key, 32};

asio::awaitable<void> start_kcp_client(asio::io_context& io_context) {
    auto [ec, socket] = co_await moon::kcp::async_connect(io_context.get_executor(), asio::ip::udp::endpoint(asio::ip::address::from_string("127.0.0.1"), 50000), magic);
    std::string string_buffer;
    string_buffer.resize(8192);
    co_await socket->async_write(asio::buffer("hello"), asio::use_awaitable);
    for (;;) {
        co_await socket->async_read_some(asio::buffer(string_buffer), asio::use_awaitable);
        std::cout << string_buffer << '\n';
    }
    co_return;
}

int main() {
    asio::io_context io_context;

    asio::signal_set signals(io_context, SIGINT, SIGTERM);
    signals.async_wait([&](auto, auto) { io_context.stop(); });

    asio::co_spawn(io_context, start_kcp_client(io_context), asio::detached);
    io_context.run();

    return 0;
}

问题: 我在调用这两个示例的时候,server.cpp中报错

Exception has occurred: W32/0xC0000005
Unhandled exception thrown: read access violation.
_Impl-> was nullptr.

image

看下是否可以了