1

I'm using the non-Boost version of Asio and have made a TCP server based on the code at http://think-async.com/Asio/asio-1.11.0/doc/asio/tutorial/tutdaytime3.html

I can establish a connection to the server just fine, but only the first time. If I disconnect my client and then attempt to connect again, Asio passes an "Already Open" error to my accept handler. As you can see from the code, before a connection is accepted, a new instance of the tcp_connection class is created. I'm not sure why I'm getting this error, even though it's a completely separate instance whose socket shouldn't already be open. Any help would be greatly appreciated.

Thanks in advance.

EDIT:

Here's the server class: http://pastebin.com/yvZmFQvA

And the client class (equivalent to the tcp_connection class in the example): http://pastebin.com/LDhr2nZz

Michael K.
  • 74
  • 7

2 Answers2

1

This might be because you are not correctly closing the socket upon disconnection. As a disconnection might happen due to an exception that can't be handled (such as signal 9), you need a solution to work even if the process didn't die gracefully...

I bealive this can solve it:

Socket options SO_REUSEADDR and SO_REUSEPORT, how do they differ? Do they mean the same across all major operating systems?

Community
  • 1
  • 1
user1708860
  • 1,683
  • 13
  • 32
  • In my tcp_connection class' async_read handler, I check to see if Asio passed it an error. If it did, I print a message, then call .shutdown() and .close() on the connection's socket after doing some cleaning up. – Michael K. Apr 25 '15 at 21:46
  • @FauxBestaan what if the program caught a signal? Such as ctrl + c? Or just kill it? Any way, try the flag in the link and let me know if it worked... – user1708860 Apr 25 '15 at 21:51
  • I actually tried setting that flag on the acceptor before to see if that was the issue. Sadly, it didn't fix anything... – Michael K. Apr 25 '15 at 22:00
  • @FauxBestaan did you try setting it on the client side? edit: Oh, you are getting the error right after accept, not right after connect.. edit2: after more tought, i still think this is the same issue. Try setting the flag on the client side too, the server side flag should affect the bind method, while the client side should force close the dead connection i think – user1708860 Apr 25 '15 at 22:11
  • I do not have access to the source code of the client. I do know that the client SHOULD be using a different local port each time it connects. I wrote a server in C# a few years back for the same client, and had no issues. I'm not sure what else to do. – Michael K. Apr 26 '15 at 00:40
0

You have:

void server::do_accept() {
    //client::pointer con = client::create(acceptor_.get_executor().context());
    client::pointer con = client::create(acceptor_.get_io_service());

    acceptor_.async_accept(con->socket(),
            std::bind(&server::on_accepted, this, con,
            std::placeholders::_1));

}

Client classes don't belong in the server. This doesn't make sense.

Your source material has:

void start_accept()
{
    tcp_connection::pointer new_connection =
      tcp_connection::create(acceptor_.get_executor().context());

    acceptor_.async_accept(new_connection->socket(),
        boost::bind(&tcp_server::handle_accept, this, new_connection,
          asio::placeholders::error));
}
user207421
  • 305,947
  • 44
  • 307
  • 483
  • As I stated in my OP, the client class is equivalent to the tcp_connection class. It's not a TCP client; It just manages a connection with a client. This was simply a naming choice and doesn't affect the code. – Michael K. Apr 26 '15 at 04:46