Skip to content

Server failed to listen again if it has already failed to listen #390

@wyyqyl

Description

@wyyqyl

Sample code.
Env: Visual Studio 2008, Windows 7

#define _CRT_SECURE_NO_WARNINGS
#define _SCL_SECURE_NO_WARNINGS

#include <websocketpp/config/asio_no_tls.hpp>

#include <websocketpp/server.hpp>

#include <iostream>

typedef websocketpp::server<websocketpp::config::asio> server;

using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
using boost::asio::ip;

typedef server::message_ptr message_ptr;

void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
  try {
    s->send(hdl, msg->get_payload(), msg->get_opcode());
  } catch (const websocketpp::lib::error_code& e) {
    std::cout << "Echo failed because: " << e
      << "(" << e.message() << ")" << std::endl;
  }
}

int main() {
  server server1;
  server server2;

  websocketpp::lib::error_code ec;

  server1.init_asio();
  server2.init_asio();

  tcp::endpoint ep1(address::from_string("127.0.0.1"), 12345);
  tcp::endpoint ep2(address::from_string("127.0.0.1"), 23456);

  server1.listen(ep1, ec);
  if (!ec) {
    server1.set_message_handler(bind(&on_message,&server1,::_1,::_2));
  }

  server2.listen(ep1, ec);
  if (ec) {
    server2.listen(ep2, ec);
    if (ec) {
      return 1;
    }
  }

  server1.start_accept();
  server1.run();
}

Here, server1 is listening on port 12345, then server2 failed to bind to port 12345, but it failed to bind any port from now on.
The reason is that you forgot to call m_acceptor->close() if listen failed. https://github.com/zaphoyd/websocketpp/blob/master/websocketpp/transport/asio/endpoint.hpp#L357

if (bec) {
    log_err(log::elevel::info,"asio listen",bec);
    ec = make_error_code(error::pass_through);
} else {
    m_state = LISTENING;
    ec = lib::error_code();
}

I think the correct way should be

if (bec) {
    if (m_acceptor->is_open()) {
      m_acceptor->close();
    }
    log_err(log::elevel::info,"asio listen",bec);
    ec = make_error_code(error::pass_through);
} else {
    m_state = LISTENING;
    ec = lib::error_code();
}

Correct me if I am wrong. Thanks!

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions