C++ Boost asio-到不同服务器的多个客户端连接

C++ Boost asio-到不同服务器的多个客户端连接,c++,boost-asio,C++,Boost Asio,我正在尝试对我的应用程序使用异步boostudp/tcp套接字操作和同步操作进行评估。我一直试图找到一个与我的设计类似的例子,但没有找到任何让我相信我可能会尝试将异步操作融入到我的设计中的东西,即使这不是正确的路径 我想连接到多个(1-10个)服务器,并使用不同的协议与它们通信;我有4-5个线程正在生成需要与这些服务器连接中的任何一个进行通信的数据 我当前的设计是同步的,每个服务器连接线程使用一个io\u服务对象,然后在产生线程和每个连接线程之间使用一个线程安全队列 这种设计在吞吐量性能方面似乎

我正在尝试对我的应用程序使用异步boostudp/tcp套接字操作和同步操作进行评估。我一直试图找到一个与我的设计类似的例子,但没有找到任何让我相信我可能会尝试将异步操作融入到我的设计中的东西,即使这不是正确的路径

我想连接到多个(1-10个)服务器,并使用不同的协议与它们通信;我有4-5个线程正在生成需要与这些服务器连接中的任何一个进行通信的数据

我当前的设计是同步的,每个服务器连接线程使用一个
io\u服务
对象,然后在产生线程和每个连接线程之间使用一个线程安全队列

这种设计在吞吐量性能方面似乎不可扩展,这是我希望最大化的


有没有提供这种到不同服务器模式的多个连接的示例?

没有包含一对多客户端服务器设计的直接示例。如果您的设计固定为最多10个连接,那么使用同步通信和每个线程就可以了。然而,如果您打算将其扩展到更大的范围,那么很明显,创建几百或几千个线程的回报会越来越小

也就是说,将
async\u connect
async\u read
async\u write
结合使用并不难理解或实现。我使用了相同的概念,仅使用少数线程就可以在上管理数千个连接。如果你选择这条路线的话,这可能是最好的学习方法


如果您正在寻找的不仅仅是示例,那么您可能会发现有几种使用Asio的方法很有用。

我已经编写了一个客户端,使用TCP/IP SSL/TLS连接到6个不同的服务器,该客户端使用Asio实现。所有6个都使用相同的协议。因此,如果有帮助,以下是我的代码:

SSLSocket.H

#pragma once

#include <cstdlib>
#include <iostream>
#include <queue>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/shared_ptr.hpp>
using namespace std;
//
#include "BufferManagement.h"
#include "Logger.h"
#include "Common Classes\Locking.h"
#include "Message.h"

class SSLSocket;
class ConcurrentMsgQueue;

#define BOOST_ASIO_ENABLE_HANDLER_TRACKING

typedef void (__stdcall *Callback)(const SSLSocket* pSSLS, const int bytesInMsg, const void* pBuf);

// typedef std::vector<boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SocketVectorType;

enum {MsgLenBytes = 4};

class SSLSocket
{
   // This class handles all communications between the client and the server
   // using TCP/IP SSL v1.  The Boost ASIO (Asynchronous I/O) library is used to accomplish this.
   // Initally written by Bob Bryan on 1/21/2013.
   //
public:
   SSLSocket(const bool logToFile, const bool logToConsole, const bool displayInHex, const LogLevel levelOfLog, const string& logFileName, const int bufMangLen);
   ~SSLSocket();
   void Connect(SSLSocket* psSLS, const string& serverPath, string& port);
   void SendToServer(const int bytesInMsg, Byte* pBuf);
   void Stop();

   static void SetCallback(Callback callbackFunction)
   {
      // This method is required in order to be able to do a reverse pinvoke from C#.
      // This callback function pointer is what is used to communicate back to the C# code.
      CallbackFunction = callbackFunction;
   }

   static Byte* AllocateMem(int length)
   {
      // Allocate some memory.  This method winds up getting called when the C# client needs to allocate some memory for a message.
      Byte* pBuf = BufMang.GetPtr(length);
      return pBuf;
   }
   //
   static Logger Log; // Object used to log info to a file and/or to the console.
   static Callback CallbackFunction; // Callback function object used to communicate with the worker thread in C#.

private:
   void InitAsynchIO();
   void HandleConnect(const boost::system::error_code& error);
   void HandleHandshake(const boost::system::error_code& error);
   void HandleFirstWrite(const boost::system::error_code& error, size_t bytes_transferred);
   void HandleRead(const boost::system::error_code& error, size_t bytesTransferred);
   // void HandleRead(const boost::system::error_code& error, size_t bytes_transferred);
   void Terminate();
   void static RcvWorkerThread(SSLSocket* sSLS);
   void static SendWorkerThread(SSLSocket* psSLS);
   void ProcessSendRequests();
   void HandleWrite(const boost::system::error_code& error, size_t bytesTransferred);
   static void WorkerThread(boost::shared_ptr< boost::asio::io_service > io_service);
   //
   struct Bytes
   {
      // Used to convert 4 bytes to an int.
      unsigned char B1;
      unsigned char B2;
      unsigned char B3;
      unsigned char B4;
   };

   union Bytes4ToInt
   {
      // Converts 4 bytes to an int.
      int IntVal;
      Bytes B;
   };

   inline int BytesToInt(const Byte * pBuf)
   {
      // This method converts 4 bytes from an array of bytes to a 4-byte int.
      B2I.B.B1 = *pBuf++;
      B2I.B.B2 = *pBuf++;
      B2I.B.B3 = *pBuf++;
      B2I.B.B4 = *pBuf;
      int Value = B2I.IntVal;
      return Value;
   }
   //
   boost::thread_group WorkerThreads; // Used to handle creating threads.
   CRITICAL_SECTION SocketLock; // Used in conjuction with the Locking object to handle single threading the code.
   boost::asio::ssl::stream<boost::asio::ip::tcp::socket>* pSocket; // Pointer to the socket object.
   Bytes4ToInt B2I; // Used to translate 4 bytes in the buffer to an int representing the number of bytes in the msg.
   std::string sClientIp; // Client IP address.  Used for logging.
   unsigned short uiClientPort; // Port number.  Used for logging.
   // static MessageList* pRepMsgs; // Link list of the msgs to send to the server.
   Byte* pDataBuf; // Pointer to the data for the current message to be read.
   static boost::shared_ptr< boost::asio::io_service > IOService; // Object required for use by ASIO to perform certain functions.
   static bool RcvThreadCreated; // Set when the rcv thread is created so that it won't try to create it again.
   static int StaticInit; // Indicates whether or not the static members have been initialized or not.
   static bool DisplayInHex; // Specifies whether to display a buffer in hex or not.
   static BufferManagement BufMang; // Smart pointer to the buffer used to handle requests coming to and from the server for all sockets.
   volatile static bool ReqAlive; // Used to indicate whether the request thread should die or not.
   // static bool RepAlive; // Used to indicate whether the response thread should die or not.
   static ConcurrentMsgQueue SendMsgQ; // Holds the messages waiting to be sent to the server.
   static HANDLE hEvent; // Used for signalling between threads.
};
#pragma一次
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
//
#包括“BufferManagement.h”
#包括“Logger.h”
#包括“公共类\Locking.h”
#包括“Message.h”
SSLSocket类;
类ConcurrentMsgQueue;
#定义BOOST\u ASIO\u启用\u处理程序\u跟踪
typedef void(u stdcall*回调)(常量SSLSocket*pSSLS、常量int bytesInMsg、常量void*pBuf);
//类型定义标准::向量io_服务);
//
结构字节
{
//用于将4个字节转换为整数。
无符号字符B1;
无符号字符B2;
无符号字符B3;
无符号字符B4;
};
联合Bytes4点
{
//将4个字节转换为整数。
int IntVal;
字节B;
};
内联int-bytestpoint(常量字节*pBuf)
{
//此方法将字节数组中的4个字节转换为4字节整数。
B2I.B.B1=*pBuf++;
B2I.B.B2=*pBuf++;
B2I.B.B3=*pBuf++;
B2I.B.B4=*pBuf;
int值=B2I.IntVal;
返回值;
}
//
boost::thread\u group WorkerThreads;//用于处理创建线程。
临界截面承插锁;//与锁定对象结合使用,以处理单线程代码。
boost::asio::ssl::stream*pSocket;//指向套接字对象的指针。
字节4点B2I;//用于将缓冲区中的4个字节转换为表示消息中字节数的int。
std::string sClientIp;//客户端IP地址。用于日志记录。
未签名的短uiClientPort;//端口号。用于日志记录。
//静态消息列表*pRepMsgs;//要发送到服务器的MSG的链接列表。
字节*pDataBuf;//指向要读取的当前消息的数据的指针。
静态boost::shared_ptrIOService;//ASIO执行某些功能所需的对象。
已创建静态bool rcvthread;//设置创建rcv线程的时间,以便它不会再次尝试创建它。
static int StaticInit;//指示静态成员是否已初始化。
静态bool displayinEx;//指定是否以十六进制显示缓冲区。
静态缓冲区管理BufMang;//指向缓冲区的智能指针,用于处理所有套接字的服务器请求。
易失性静态bool ReqAlive;//用于指示请求线程是否应该消亡。
//静态bool-RepAlive;//用于指示响应线程是否应该死亡。
静态ConcurrentMsgQueue SendMsgQ;//保存等待发送到服务器的邮件。
静态句柄hEvent;//用于在线程之间发送信号。
};
SSLSocket.cpp

#include "StdAfx.h"
#include "SSLSocket.h"

boost::shared_ptr< boost::asio::io_service > SSLSocket::IOService;
int SSLSocket::StaticInit = 0;
Callback SSLSocket::CallbackFunction;
BufferManagement SSLSocket::BufMang;
volatile bool SSLSocket::ReqAlive = true;
Logger SSLSocket::Log;
HANDLE SSLSocket::hEvent;
bool SSLSocket::DisplayInHex;
ConcurrentMsgQueue SSLSocket::SendMsgQ;
bool SSLSocket::RcvThreadCreated = 0;
BufferManagement* Message::pBufMang;

SSLSocket::SSLSocket(const bool logToFile, const bool logToConsole, const bool displayInHex,
   const LogLevel levelOfLog, const string& logFileName, const int bufMangLen) : pSocket(0)
{
   // SSLSocket Constructor.
   // If the static members have not been intialized yet, then initialize them.
   if (!StaticInit)
   {
      DisplayInHex = displayInHex;
      BufMang.Init(bufMangLen);
      Message::SetBufMang(&BufMang);
      // This constructor enables logging according to the vars passed in.
      Log.Init(logToFile, logToConsole, levelOfLog, logFileName);
      // Create the crit section object
      // Locking::InitLocking(ReadLock);
      // Locking::InitLocking(WriteLock);
      StaticInit++;
      hEvent = CreateEvent(NULL, false, false, NULL);
      // Define the ASIO IO service object.
      // IOService = new boost::shared_ptr<boost::asio::io_service>(new boost::asio::io_service);
      boost::shared_ptr<boost::asio::io_service> IOServ(new boost::asio::io_service);
      IOService = IOServ;
   }
}

SSLSocket::~SSLSocket(void)
{
   delete pSocket;
   if (--StaticInit == 0)
      CloseHandle(hEvent);
}

void SSLSocket::Connect(SSLSocket* psSLS, const string& serverPath, string& port)
{
   // Connects to the server.
   // serverPath - specifies the path to the server.  Can be either an ip address or url.
   // port - port server is listening on.
   //
   try
   {
      Locking CodeLock(SocketLock); // Single thread the code.
      // If the user has tried to connect before, then make sure everything is clean before trying to do so again.
      if (pSocket)
      {
         delete pSocket;
         pSocket = 0;
      }                                                                                                  
      // If serverPath is a URL, then resolve the address.
      // Note that this code expects the first server to always have a url.
      if ((serverPath[0] < '0') || (serverPath[0] > '9')) // Assumes that the first char of the server path is not a number when resolving to an ip addr.
      {
         // Create the resolver and query objects to resolve the host name in serverPath to an ip address.
         boost::asio::ip::tcp::resolver resolver(*IOService);
         boost::asio::ip::tcp::resolver::query query(serverPath, port);
         boost::asio::ip::tcp::resolver::iterator EndpointIterator = resolver.resolve(query);
         // Set up an SSL context.
         boost::asio::ssl::context ctx(*IOService, boost::asio::ssl::context::tlsv1_client);
         // Specify to not verify the server certificiate right now.
         ctx.set_verify_mode(boost::asio::ssl::context::verify_none);
         // Init the socket object used to initially communicate with the server.
         pSocket = new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(*IOService, ctx);
         //
         // The thread we are on now, is most likely the user interface thread.  Create a thread to handle all incoming socket work messages.
         if (!RcvThreadCreated)
         {
            WorkerThreads.create_thread(boost::bind(&SSLSocket::RcvWorkerThread, this));
            RcvThreadCreated = true;
            WorkerThreads.create_thread(boost::bind(&SSLSocket::SendWorkerThread, this));
         }
         // Try to connect to the server.  Note - add timeout logic at some point.
         boost::asio::async_connect(pSocket->lowest_layer(), EndpointIterator,
            boost::bind(&SSLSocket::HandleConnect, this, boost::asio::placeholders::error));
      }
      else
      {
         // serverPath is an ip address, so try to connect using that.
         //
         // Create an endpoint with the specified ip address.
         const boost::asio::ip::address IP(boost::asio::ip::address::from_string(serverPath));
         int iport = atoi(port.c_str());
         const boost::asio::ip::tcp::endpoint EP(IP, iport);
         // Set up an SSL context.
         boost::asio::ssl::context ctx(*IOService, boost::asio::ssl::context::tlsv1_client);
         // Specify to not verify the server certificiate right now.
         ctx.set_verify_mode(boost::asio::ssl::context::verify_none);
         // Init the socket object used to initially communicate with the server.
         pSocket = new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(*IOService, ctx);
         //
         // Try to connect to the server.  Note - add timeout logic at some point.
         //pSocket->core_.engine_.do_connect(void*, int);
         // pSocket->next_layer_.async_connect(EP, &SSLSocket::HandleConnect)
         // pSocket->next_layer().async_connect(EP, &SSLSocket::HandleConnect);
         boost::system::error_code EC;
         pSocket->next_layer().connect(EP, EC);
         if (EC)
         {
            // Log an error.  This worker thread should exit gracefully after this.
            stringstream ss;
            ss << "SSLSocket::Connect: connect failed to " << sClientIp << " : " << uiClientPort << ".  Error: " << EC.message() + ".\n";
            Log.LogString(ss.str(), LogError);
         }
         HandleConnect(EC);
         // boost::asio::async_connect(pSocket->lowest_layer(), EP,
         //   boost::bind(&SSLSocket::HandleConnect, this, boost::asio::placeholders::error));
      }
   }
   catch (std::exception& e)
   {
      stringstream ss;
      ss << "SSLSocket::Connect: threw an error - " << e.what() << ".\n";
      Log.LogString(ss.str(), LogError);
      Stop();
   }
}

void SSLSocket::SendToServer(const int bytesInMsg, Byte* pBuf)
{
   // This method creates a msg object and saves it in the SendMsgQ object.
   // sends the number of bytes specified by bytesInMsg in pBuf to the server.
   //
   Message* pMsg = Message::GetMsg(this, bytesInMsg, pBuf);
   SendMsgQ.Push(pMsg);
   // Signal the send worker thread to wake up and send the msg to the server.
   SetEvent(hEvent);
}


void SSLSocket::SendWorkerThread(SSLSocket* psSLS)
{
   // This thread method that gets called to process the messages to be sent to the server.
   //
   // Since this has to be a static method, call a method on the class to handle server requests.
   psSLS->ProcessSendRequests();
}

void SSLSocket::ProcessSendRequests()
{
   // This method handles sending msgs to the server.
   //
   std::stringstream ss;
   DWORD WaitResult;
   Log.LogString("SSLSocket::ProcessSendRequests: Worker thread " + Logger::NumberToString(boost::this_thread::get_id()) + " started.\n", LogInfo);
   // Loop until the user quits, or an error of some sort is thrown.
   try
   {
      do
      {
         // If there are one or more msgs that need to be sent to a server, then send them out.
         if (SendMsgQ.Count() > 0)
         {
            Message* pMsg = SendMsgQ.Front();
            SSLSocket* pSSL = pMsg->pSSL;
            SendMsgQ.Pop();
            const Byte* pBuf = pMsg->pBuf;
            const int BytesInMsg = pMsg->BytesInMsg;
            boost::system::error_code Error;
            {
               Locking CodeLock(SocketLock); // Single thread the code.
               boost::asio::async_write(*pSSL->pSocket, boost::asio::buffer(pBuf, BytesInMsg), boost::bind(&SSLSocket::HandleWrite, this,
                  boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
            }
            ss << "SSLSocket::ProcessSendRequests: # bytes sent = " << BytesInMsg << "\n";
            Log.LogString(ss.str(), LogDebug2);
            Log.LogBuf(pBuf, BytesInMsg, DisplayInHex, LogDebug3);
         }
         else
         {
            // Nothing to send, so go into a wait state.
            WaitResult = WaitForSingleObject(hEvent, INFINITE);
            if (WaitResult != 0L)
            {
               Log.LogString("SSLSocket::ProcessSendRequests: WaitForSingleObject event error.  Code = " + Logger::NumberToString(GetLastError()) + ". \n", LogError);
            }
         }
      } while (ReqAlive);
      Log.LogString("SSLSocket::ProcessSendRequests: Worker thread " + Logger::NumberToString(boost::this_thread::get_id()) + " done.\n", LogInfo);
   }
   catch (std::exception& e)
   {
      stringstream ss;
      ss << "SSLSocket::ProcessSendRequests: threw an error - " << e.what() << ".\n";
      Log.LogString(ss.str(), LogError);
      Stop();
   }
}

void SSLSocket::HandleWrite(const boost::system::error_code& error, size_t bytesTransferred)
{
   // This method is called after a msg has been written out to the socket.  Nothing to do really since reading is handled by the HandleRead method.

   std::stringstream ss;
   try
   {
      if (error)
      {
         ss << "SSLSocket::HandleWrite: failed - " << error.message() << ".\n";
         Log.LogString(ss.str(), LogError);
         Stop();
      }
   }
   catch (std::exception& e)
   {
      stringstream ss;
      ss << "SSLSocket::HandleHandshake: threw an error - " << e.what() << ".\n";
      Log.LogString(ss.str(), LogError);
      Stop();
   }
}

void SSLSocket::RcvWorkerThread(SSLSocket* psSLS)
{
   // This is the method that gets called when the receive thread is created by this class.
   // This thread method focuses on processing messages received from the server.
   //
   // Since this has to be a static method, call a method on the class to handle server requests.
   psSLS->InitAsynchIO();
}

void SSLSocket::InitAsynchIO()
{
   // This method is responsible for initiating asynch i/o.
   boost::system::error_code Err;
   string s;
   stringstream ss;
   //
   try
   {
      ss << "SSLSocket::InitAsynchIO: Worker thread - " << Logger::NumberToString(boost::this_thread::get_id()) << " started.\n";
      Log.LogString(ss.str(), LogInfo);
      // Enable the handlers for asynch i/o.  The thread will hang here until the stop method has been called or an error occurs.
      // Add a work object so the thread will be dedicated to handling asynch i/o.
      boost::asio::io_service::work work(*IOService);
      IOService->run();
      Log.LogString("SSLSocket::InitAsynchIO: receive worker thread done.\n", LogInfo);
   }
   catch (std::exception& e)
   {
      stringstream ss;
      ss << "SSLSocket::InitAsynchIO: threw an error - " << e.what() << ".\n";
      Log.LogString(ss.str(), LogError);
      Stop();
   }
}

void SSLSocket::HandleConnect(const boost::system::error_code& error)
{
   // This method is called asynchronously when the server has responded to the connect request.
   std::stringstream ss;
   try
   {
      if (!error)
      {
         pSocket->async_handshake(boost::asio::ssl::stream_base::client,
            boost::bind(&SSLSocket::HandleHandshake, this, boost::asio::placeholders::error));
         ss << "SSLSocket::HandleConnect: From worker thread " << Logger::NumberToString(boost::this_thread::get_id()) << ".\n";
         Log.LogString(ss.str(), LogInfo);
      }
      else
      {
         // Log an error.  This worker thread should exit gracefully after this.
         ss << "SSLSocket::HandleConnect: connect failed to " << sClientIp << " : " << uiClientPort << ".  Error: " << error.message() + ".\n";
         Log.LogString(ss.str(), LogError);
         Stop();
      }
   }
   catch (std::exception& e)
   {
      stringstream ss;
      ss << "SSLSocket::InitAsynchIO: threw an error - " << e.what() << ".\n";
      Log.LogString(ss.str(), LogError);
      Stop();
   }
}

void SSLSocket::HandleHandshake(const boost::system::error_code& error)
{
   // This method is called asynchronously when the server has responded to the handshake request.
   std::stringstream ss;
   try
   {
      if (!error)
      {
         // Try to send the first message that the server is expecting.  This msg tells the server we want to start communicating.
         // This is the only msg specified in the C++ code.  All other msg processing is done in the C# code.
         //
         unsigned char Msg[27] = {0x17, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x41,
            0x74, 0x74, 0x61, 0x63, 0x6b, 0x50, 0x6f, 0x6b, 0x65, 0x72, 0x02, 0x00, 0x65, 0x6e};
         boost::system::error_code Err;

         sClientIp = pSocket->lowest_layer().remote_endpoint().address().to_string();
         uiClientPort = pSocket->lowest_layer().remote_endpoint().port();
         ReqAlive = true;
         // boost::asio::async_write(*pSocket, boost::asio::buffer(Msg), boost::bind(&SSLSocket::HandleFirstWrite, this,
         //   boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
         int Count = boost::asio::write(*pSocket, boost::asio::buffer(Msg), boost::asio::transfer_exactly(27), Err);
         if (Err)
         {
            ss << "SSLSocket::HandleHandshake: write failed - " << error.message() << ".\n";
            Log.LogString(ss.str(), LogInfo);
         }
         HandleFirstWrite(Err, Count);
         // boost::asio::async_write(pSocket, boost::asio::buffer(Msg, 27), boost::bind(&SSLSocket::HandleWrite, this,
         // boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
         ss.str("");
         ss << "SSLSocket::HandleHandshake: From worker thread " << boost::this_thread::get_id() << ".\n";
      }
      else
      {
         ss << "SSLSocket::HandleHandshake: failed - " << error.message() << ".\n";
         IOService->stop();
      }
      Log.LogString(ss.str(), LogInfo);
   }
   catch (std::exception& e)
   {
      stringstream ss;
      ss << "SSLSocket::HandleHandshake: threw an error - " << e.what() << ".\n";
      Log.LogString(ss.str(), LogError);
      Stop();
   }
}

void SSLSocket::HandleFirstWrite(const boost::system::error_code& error, size_t bytesTransferred)
{
   // This method is called after a msg has been written out to the socket.
   std::stringstream ss;
   try
   {
      if (!error)
      {
         // boost::asio::async_read(pSocket, boost::asio::buffer(reply_, bytesTransferred), boost::bind(&SSLSocket::handle_read,
         //   this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
         // boost::asio::async_read(pSocket, boost::asio::buffer(reply_, 84), boost::bind(&SSLSocket::handle_read,
         //   this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
         // Locking CodeLock(ReadLock); // Single thread the code.
         // Signal the other threads that msgs are now ready to be sent and received.
         // boost::asio::async_read(pSocket, boost::asio::buffer(pRepBuf), boost::asio::transfer_exactly(4), boost::bind(&SSLSocket::HandleRead,
         //  this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
         //
         // Notify the UI that we are now connected.  Create a 6 byte msg for this.
         pDataBuf = BufMang.GetPtr(6);
         BYTE* p = pDataBuf;
         // Create msg type 500
         *p = 244;
         *++p = 1;
         CallbackFunction(this, 2, (void*)pDataBuf);
         // Get the 1st 4 bytes of the next msg, which is always the length of the that msg.
         pDataBuf = BufMang.GetPtr(MsgLenBytes);

         // int i1=1,i2=2,i3=3,i4=4,i5=5,i6=6,i7=7,i8=8,i9=9;
         //   (boost::bind(&nine_arguments,_9,_2,_1,_6,_3,_8,_4,_5,_7))
         //     (i1,i2,i3,i4,i5,i6,i7,i8,i9);

         // boost::asio::read(*pSocket, boost::asio::buffer(pReqBuf, MsgLenBytes), boost::asio::transfer_exactly(MsgLenBytes), Err);
         // boost::asio::async_read(pSocket, boost::asio::buffer(pReqBuf, MsgLenBytes), boost::bind(&SSLSocket::HandleRead, _1,_2,_3))
         //   (this, pReqBuf, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred);
         //   boost::asio::async_read(*pSocket, boost::asio::buffer(reply_), boost::asio::transfer_exactly(ByteCount), boost::bind(&Client::handle_read,
         //      this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
         // boost::asio::async_write(*pSocket, boost::asio::buffer(pDataBuf, MsgLenBytes), boost::bind(&SSLSocket::HandleWrite, this,
         //    boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));

         Locking CodeLock(SocketLock); // Single thread the code.
         boost::asio::async_read(*pSocket, boost::asio::buffer(pDataBuf, MsgLenBytes), boost::bind(&SSLSocket::HandleRead, this,
            boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
      }
      else
      {
         ss << "SSLSocket::HandleFirstWrite: failed - " << error.message() << ".\n";
         Log.LogString(ss.str(), LogError);
         Stop();
      }
   }
   catch (std::exception& e)
   {
      stringstream ss;
      ss << "SSLSocket::HandleFirstWrite: threw an error - " << e.what() << ".\n";
      Log.LogString(ss.str(), LogError);
      Stop();
   }
}

void SSLSocket::HandleRead(const boost::system::error_code& error, size_t bytesTransferred)
{
   // This method is called to process an incomming message.
   //
   std::stringstream ss;
   int ByteCount;
   try
   {
       ss << "SSLSocket::HandleRead: From worker thread " << boost::this_thread::get_id() << ".\n";
      Log.LogString(ss.str(), LogInfo);
      // Set to exit this thread if the user is done.
      if (!ReqAlive)
      {
         // IOService->stop();
         return;
      }
      if (!error)
      {
         // Get the number of bytes in the message.
         if (bytesTransferred == 4)
         {
            ByteCount = BytesToInt(pDataBuf);
         }
         else
         {
            // Call the C# callback method that will handle the message.
            ss << "SSLSocket::HandleRead: From worker thread " << boost::this_thread::get_id() << "; # bytes transferred = " << bytesTransferred << ".\n";
            Log.LogString(ss.str(), LogDebug2);
            Log.LogBuf(pDataBuf, (int)bytesTransferred, true, LogDebug3);
            Log.LogString("SSLSocket::HandleRead: sending msg to the C# client.\n\n", LogDebug2);
            CallbackFunction(this, bytesTransferred, (void*)pDataBuf);
            // Prepare to read in the next message length.
            ByteCount = MsgLenBytes;
         }
         pDataBuf = BufMang.GetPtr(ByteCount);
         boost::system::error_code Err;
         // boost::asio::async_read(pSocket, boost::asio::buffer(pDataBuf, ByteCount), boost::bind(&SSLSocket::HandleRead,
           //  this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
         Locking CodeLock(SocketLock); // Single thread the code.
         boost::asio::async_read(*pSocket, boost::asio::buffer(pDataBuf, ByteCount), boost::bind(&SSLSocket::HandleRead,
            this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
         // boost::asio::read(pSocket, boost::asio::buffer(reply_), boost::asio::transfer_exactly(ByteCount), Err);
      }
      else
      {
         Log.LogString("SSLSocket::HandleRead failed: " + error.message() + "\n", LogError);
         Stop();
      }
   }
   catch (std::exception& e)
   {
      stringstream ss;
      ss << "SSLSocket::HandleRead: threw an error - " << e.what() << ".\n";
      Log.LogString(ss.str(), LogError);
      Stop();
   }
}

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.
   ReqAlive = false;
   SetEvent(hEvent);
   IOService->stop();
}
#包括“StdAfx.h”
#包括“SSLSocket.h”
boost::shared_ptrSSLSocket::IOService;
int-SSLSocket::StaticInit=0;
回调SSLSocket::CallbackFunction;
BufferManagement SSLSocket::BufMang;
volatile bool SSLSocket::ReqAlive=true;
记录器SSLSocket::Log;
手柄SSLSocket::hEvent;
boolssocket::displayinEx;
ConcurrentMsgQueue SSLSocket::SendMsgQ;
bool SSLSocket::RcvThreadCreated=0;
BufferManagement*消息::pBufMang;
SSLSocket::SSLSocket(const bool logToFile、const bool logToConsole、const bool displayinEx、,
const LogLevel levelOfLog、const string和logFileName、const int bufMangLen):pSocket(0)
{
//SSLSocket构造函数。
//如果静态成员尚未初始化,则初始化它们。
如果(!StaticInit)
{
DisplayInHex=DisplayInHex;
BufMang.Init(bufMangLen);
消息::SetBufMang(&BufMang);
//此构造函数根据传入的变量启用日志记录。
Init(logToFile、logToConsole、levelOfLog、logFileName);
//创建crit部分对象
//锁定::InitLocking(ReadLock);
//锁定::InitLocking(WriteLock);
StaticInit++;
hEvent=CreateEvent(NULL,false,false,NULL);
//定义ASIO