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