5

I'm using boost 1.54.0 with OpenSSL 1.0.1e.

When closing SSL connection object from time to time I see that completion handler of async_shutdown() is not called.

After debugging I found out, that this happenes when there's outstaing async_write().

SSL async_shutdown() should send SSL Alert(Closing), thus we have here 2 writes. I know that multiple async_write()'s are forbidden.

How I should handle the situation? Should I wait for async_write() completion before calling SSL async_shutdown()?

EDIT: According to this I probably need cancel() on underlying TCP socket to cancel all outstanding async-operations. Is it correct?

EDIT If I'm using async_ API all the time, can I call shutdown() or I must call async_shutdown()?

4

1 回答 1

2

这就是我处理关机的方式。在此之前,我遇到了关闭问题。这段代码干净利落地关闭了一切:

void SSLSocket::Stop()
{
   // This method calls the shutdown method on the socket in order to stop reads or writes that might be going on.  If this is not done, then an exception will be thrown
   // when it comes time to delete this object.
   //
   boost::system::error_code EC;
   try
   {
      // This method can be called from the handler as well.  So once the ShuttingDown flag is set, don't go throught the same code again.
      //
      LockCode->Acquire(); // Single thread the code.
      if (ShuttingDown)
         return;
      ShuttingDown = true;
      pSocket->next_layer().cancel();
      pSocket->shutdown(EC);
      if (EC)
      {
         stringstream ss;
         ss << "SSLSocket::Stop: socket shutdown error - " << EC.message() << ".\n";
         // Log.LogString(ss.str(), LogError); // Usually get this - probably not an error.
      }
      else
      {
         pSocket->next_layer().close();
      }
      delete pSocket;
      pSocket = 0;
      ReqAlive = false;
      SetEvent(hEvent);
      IOService->stop();
      LobbySocketOpen = false;
      WorkerThreads.join_all();
      LockCode->Release();
      delete LockCode;
      LockCode = 0;
   }
   catch (std::exception& e)
   {
      stringstream ss;
      ss << "SSLSocket::Stop: threw an error - " << e.what() << ".\n";
      Log.LogString(ss.str(), LogError);
      Stop();
   }
}
于 2013-08-22T16:09:59.530 回答