boost :: asio :: async_write неправильно пишет клиентам, странное поведение - PullRequest
1 голос
/ 19 мая 2011

Я написал программу, которая принимает N клиентских подключений, а затем записывает в них данные. Проблема, с которой я сталкиваюсь сейчас: я могу писать только клиентам N-1, первый никогда не пишется. Я понятия не имею, почему это происходит, и поэтому я хотел бы, чтобы некоторые из вас могли оказать некоторую помощь.

Я предоставил часть кода, которая может быть связана с этой проблемой:

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;
}

Спасибо за любую помощь.

1 Ответ

1 голос
/ 19 мая 2011

Первый async_accept() вызывается на acceptingSocket, который new 'd в AcceptClientConnections() и протекает.

Последующие async_accept() s вызываются на сокетах, которые new'd в HandleAccept() и push_back() 'ed в m_clientSockets.

WriteToClient() выполняется только для сокетов, найденных в m_clientSockets, но не в первом сокете.

Решение: push_back этот первый сокет в AcceptClientConnections() в m_clientSockets тоже.

...