2012-10-26 45 views
-2

我应该使用什么样的锁来解决使用recieveBuffer的可能冲突? (锁定/解锁)。如何使用锁定缓冲区

下面是客户端代码与我的坏锁:

class TCPClient 
{ 
    public: 
     static const size_t maxBufLen = 100; 
     static const size_t MAX_INPUT_SIZE = 10; 

     TCPClient(boost::asio::io_service& IO_Service, tcp::resolver::iterator EndPointIter); 
     void close(); 

    private: 
     boost::asio::io_service& m_IOService; 
     tcp::socket m_Socket; 

     char recieveBuffer[maxBufLen]; 

     void promptTxMsgLoop(); 
     void onConnect(const boost::system::error_code& ErrorCode, tcp::resolver::iterator EndPointIter); 
     void onReceive(const boost::system::error_code& ErrorCode); 
     void onSend(const boost::system::error_code& ErrorCode); 
     void doClose(); 
}; 


TCPClient::TCPClient(boost::asio::io_service& IO_Service, tcp::resolver::iterator EndPointIter) 
: m_IOService(IO_Service), m_Socket(IO_Service) 
{ 
    tcp::endpoint EndPoint = *EndPointIter; 
    recieveBuffer[0] = '\0'; 

    m_Socket.async_connect(EndPoint, 
     boost::bind(&TCPClient::onConnect, this, boost::asio::placeholders::error, ++EndPointIter)); 
} 


void TCPClient::onConnect(const boost::system::error_code& ErrorCode, tcp::resolver::iterator EndPointIter) 
{ 
    if (ErrorCode == 0) 
    { 
     this->promptTxMsgLoop(); 
    } 
    else if (EndPointIter != tcp::resolver::iterator()) 
    { 
     cout << "m_Socket.close();!" << endl; 
     m_Socket.close(); 
     tcp::endpoint EndPoint = *EndPointIter; 

     m_Socket.async_connect(EndPoint, 
      boost::bind(&TCPClient::onConnect, this, boost::asio::placeholders::error, ++EndPointIter)); 
    } 
} 

void TCPClient::promptTxMsgLoop() 
{ 
    recieveBuffer[0] = '\0'; 
    while (true) 
    { 
     cout << "> " ; 
     string tmp; 
     cin >> tmp; 

     cout << "Entered: " << tmp << endl; 
     tmp += "\0"; 

     if (tmp.length() < MAX_INPUT_SIZE-1) 
     { 
      try 
      { 
       //lock untill buffer is emty 
       while (strlen(recieveBuffer) > 1) 
       { 

       } 
       m_Socket.async_send(boost::asio::buffer(tmp.c_str(),tmp.length()+1), 
        boost::bind(&TCPClient::onSend, this, boost::asio::placeholders::error)); 
      } 
      catch(exception &e) 
      { 
       cerr << "Cannot add msg to send queue... " << e.what() << endl; 
      } 
     } 
     else 
      cout << "Error: input string is too long. Max length is " << MAX_INPUT_SIZE-1 << endl; 
    } 
} 

void TCPClient::onSend(const boost::system::error_code& ErrorCode) 
{ 
    cout << "Msg has been sent..." << endl; 

    if (strlen(recieveBuffer) > 1) 
     cout << "ERROR: recieveBuffer in not epmty. Data is overritten!" << endl; 

    if (!ErrorCode) 
    { 
     m_Socket.async_receive(boost::asio::buffer(recieveBuffer, TCPClient::maxBufLen), 
      boost::bind(&TCPClient::onReceive, this, boost::asio::placeholders::error)); 
    } 
    else 
    { 
     cout << "onSend closing" << endl; 
     cout << "ERROR! onSend..." << ErrorCode << endl; 
     doClose(); 
    } 
} 

void TCPClient::onReceive(const boost::system::error_code& ErrorCode) 
{ 
    cout << "Msg has been received..." << endl; 

    if (ErrorCode == 0) 
    { 
     cout << recieveBuffer << endl; 
     cout << "msg length: " << strlen(recieveBuffer) << endl; 

     //unlock buffer 
     recieveBuffer[0] = '\0'; 
    } 
    else 
    { 
     cout << "ERROR! onReceive..." << ErrorCode << endl; 
     doClose(); 
    } 
} 

void TCPClient::doClose() 
{ 
    m_Socket.close(); 
} 

int main() 
{ 
    try 
    { 
     boost::asio::io_service IO_Service; 
     tcp::resolver Resolver(IO_Service); 
     tcp::resolver::query Query("127.0.0.1", "1"); 
     tcp::resolver::iterator EndPointIterator = Resolver.resolve(Query); 
     TCPClient Client(IO_Service, EndPointIterator); 
     boost::thread ClientThread(boost::bind(&boost::asio::io_service::run, &IO_Service)); 
     ClientThread.join(); 
     Client.close(); 
    } 
    catch (exception& e) 
    { 
     cerr << e.what() << endl; 
    } 

    cout << "\nClosing"; 
    getch(); 

} 

回答

1

你可能寻找一个mutex锁(又名“mutal排斥锁”)。

+0

使用互斥锁似乎是好的。但是,我应该改变当前的缓冲区类型? – Torrius

+0

像你这样的char数组很常见,它应该适合你。 – hexist