mercredi 2 décembre 2015

asio connect to server causes: You were not connected because

i wrote a client for a tcp server which works fine compiled without optimization but does not work fine if compiled in release mode.

After a couple thousands of connections i do get:

You were not connected because a duplicate name exists on the network. If joining a domain, go to System in Control Panel to change the computer name and try again. If joining a workgroup, choose another workgroup name.

I am trying to esablish to dump a million things with this which always create a new connection for it and closes it after usage.

For every sending i do create a CLink which does look like this:

class CLink
{
public:
    explicit CLink(asio::io_service& service, const std::string& host, const std::string& port, const int& i = 1000);
    ~CLink();
    void operator>>(std::shared_ptr<std::string> get);
    void operator<<(std::shared_ptr<std::string> tosend);
private:
    template<typename AllowTime> void await_operation(AllowTime const& deadline_or_duration);
    char* read(const size_t& count);
    asio::ip::tcp::socket m_socket;
    int m_timeout;
};

template <typename AllowTime>
void CLink::await_operation(AllowTime const& deadline_or_duration)
{
    using namespace asio;
    auto& ioservice = m_socket.get_io_service();
    ioservice.reset();
    {
        asio::steady_timer tm(ioservice, deadline_or_duration);
        tm.async_wait([this](std::error_code ec)
        {
            //timer was not cancled so it run out
            if (ec != error::operation_aborted)
            {
                m_socket.cancel();
            }
        });
        ioservice.poll_one();
    }
    ioservice.run();
}


#define MESSAGE_SIZE 8
namespace jimdb
{
    CLink::CLink(asio::io_service& service, const std::string& host, const std::string& port,
                 const int& i) : m_socket(service),
        m_timeout(i)
    {
        asio::ip::tcp::resolver l_res(service);
        asio::ip::tcp::resolver::query l_query(asio::ip::tcp::v4(), host, port);
        asio::async_connect(m_socket, l_res.resolve(l_query),
                            [&](std::error_code ec, asio::ip::tcp::resolver::iterator it)
        {
            if (ec) throw std::runtime_error(ec.message());
        });
        await_operation(std::chrono::milliseconds(m_timeout));
    }

    CLink::~CLink()
    {
        m_socket.close();
    }

    void CLink::operator>>(std::shared_ptr<std::string> get)
    {
        auto l_buffer = read(MESSAGE_SIZE);
        if (l_buffer == nullptr)
        {
            get = nullptr;
            return;
        }

        //never use atoi
        auto l_size = 0;
        std::stringstream ss;
        ss << l_buffer;
        ss >> l_size;

        delete[] l_buffer;

        if (l_size == 0)
        {
            get = nullptr;
            return;
        }

        l_buffer = read(l_size);
        if (l_buffer != nullptr)
        {
            get->append(l_buffer);
            delete[] l_buffer;
            return;
        }

        get = nullptr;
        return;
    }

    void CLink::operator<<(std::shared_ptr<std::string> tosend)
    {
        if (tosend == nullptr)
            return;
        char length[MESSAGE_SIZE + 1];
        sprintf(length, "%8d", static_cast<int>(tosend->size()));
        auto l_message = std::string(length);
        l_message += *tosend;

        //this doesnt like string itself getting xstring issues so go for the cstring.
        asio::async_write(m_socket, asio::buffer(l_message.c_str(), l_message.size()), [&](std::error_code ec,
        size_t bytes_read) {});
        await_operation(std::chrono::seconds(1));
    }

    char* CLink::read(const size_t& count)
    {
        auto l_buffer = new char[count + 1];
        l_buffer[count] = '\0';
        asio::async_read(m_socket, asio::buffer(l_buffer, count), [&](std::error_code ec, size_t bytes_read)
        {
            if (ec)
                LOG_ERROR << ec.message();
        });
        //wait for the task to finish
        await_operation(std::chrono::milliseconds(m_timeout));
        return l_buffer;
    }
}

Example usage in a connector class which holds the only asio io_service:

std::shared_ptr<std::string> Connector::send(std::shared_ptr<std::string> json)
{
    CLink link(m_service, m_host, m_port);

    if (handShake(link))
    {
        link << json;
        auto recv = std::make_shared<std::string>("");
        link >> recv;
        return recv;
    }

    return nullptr;
}

I did try:

  • http://ift.tt/1jy2XFq
  • also change the server to reuse sockets
  • debug (O0) works fine but sure is slower in connecting
  • release(O2) does not work
  • flags for asio are set

What does cause the issue and how do i solve it?

Aucun commentaire:

Enregistrer un commentaire