czchlong
czchlong

Reputation: 2574

boost::asio::async_write not writing to clients properly, weird behaviour

I have written a program that accepts N client connections and then writes data into them. The problem I am having now is: I can only write to N-1 clients, the first one is never written to. I have no idea why this is happening and so I wish some of you might be able to provide some assistance.

I have provided the portion of code that may be associated with this problem:

void ClientPartitionServer::AcceptClientConnections(int port) {
  cout << "Listening to connections..." << endl;
  cout << "Number of PartitionInstanceConnections: " <<
    m_partitionInstanceConnections.size() << endl;
  m_acceptor = new boost::asio::ip::tcp::acceptor(m_IOService);
  m_endpoint = new boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(),
    m_port);
  m_acceptor->open(m_endpoint->protocol());
  m_acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
  m_acceptor->bind(*m_endpoint);
  m_acceptor->listen();
  boost::asio::ip::tcp::socket* acceptingSocket =
    new boost::asio::ip::tcp::socket(m_IOService);
  m_acceptor->async_accept(*acceptingSocket, boost::bind(
    &ClientPartitionServer::HandleAccept, this, acceptingSocket,
    boost::asio::placeholders::error));
}
void ClientPartitionServer::HandleAccept(boost::asio::ip::tcp::socket* socket,
    const boost::system::error_code& error) {
  cout << "Connection established..." << endl;
  m_clientSockets.push_back(new boost::asio::ip::tcp::socket(m_IOService));
  cout << m_clientSockets.back()->is_open() << endl;
  ++m_clientSocketsCounter;
  cout << "ClientPartitionServer identifier: " << m_identifier << endl;
  cout << "Client connected on port:         " << m_port << endl;
  cout << "Number of clients on port:        " << m_clientSocketsCounter <<
    endl;
  m_acceptor->async_accept(*m_clientSockets.back(), boost::bind(
    &ClientPartitionServer::HandleAccept, this, m_clientSockets.back(),
    boost::asio::placeholders::error));
}

void ClientPartitionServer::HandleSignal(char* content, int transferSize,
    int identifier) {
  if(identifier == m_identifier) {
    TransferToQueueBuffer(content, transferSize);
    if(m_writeCompleteFlag) {
      TransferToWriteBuffer(m_queueBuffer, m_queueBufferSize);
      if(m_clientSockets.size() != 0) {
        for(vector<boost::asio::ip::tcp::socket*>::const_iterator i =
            m_clientSockets.begin(); i != m_clientSockets.end(); ++i) {
          WriteToClient(m_writeBuffer, m_queueBufferSize, *i);
        }
      }
    }
  }
}

void ClientPartitionServer::WriteToClient(char* content, int transferSize,
    boost::asio::ip::tcp::socket* clientSocket) {
  boost::lock_guard<boost::mutex> lock(m_writeToClientMutex);
  m_writeCompleteFlag = false;
  boost::asio::async_write(*clientSocket, boost::asio::buffer("ABC ",
    4), boost::bind(&ClientPartitionServer::HandleWrite,
      this, boost::asio::placeholders::error,
      boost::asio::placeholders::bytes_transferred));
}

void ClientPartitionServer::HandleWrite(const boost::system::error_code& ec,
    size_t bytes_transferred) {
  cout << "handlewrite" << endl;
  m_writeCompleteFlag = true;
}

Thank you for any assistance.

Upvotes: 1

Views: 324

Answers (1)

Cubbi
Cubbi

Reputation: 47408

The first async_accept() is called on acceptingSocket which is new'd in AcceptClientConnections() and leaked.

The subsequent async_accept()s are called on sockets that are new'd in HandleAccept() and push_back()'ed into m_clientSockets.

WriteToClient() is executed only on the sockets found in m_clientSockets, never on the first socket.

Solution: push_back that first socket in AcceptClientConnections() into m_clientSockets too.

Upvotes: 1

Related Questions