2 Stimmen

So spülen Sie die Steckdose mit Boost

Ich implementiere einen Server, der Xml mit Boost an Clients sendet. Das Problem, dem ich gegenüberstehe, ist, dass der Puffer nicht sofort gesendet wird, sondern sich bis zu einem bestimmten Punkt ansammelt und dann das ganze Ding sendet. Dies führt zu einem Problem auf meiner Client-Seite, wenn es die Xml parst, kann es unvollständige Xml-Tag (unvollständige Nachricht) haben. Gibt es eine Möglichkeit, in Boost den Socket zu leeren, wenn eine Nachricht gesendet werden muss? Unten ist der Schreibcode des Servers.

void 
ClientConnection::handle_write(const boost::system::error_code& error)
{

    if (!error)
    {

        m_push_message_queue.pop_front ();
        if (!m_push_message_queue.empty () && !m_disconnected)
        {

             boost::asio::async_write(m_socket,
            boost::asio::buffer(m_push_message_queue.front().data(), 
                        m_push_message_queue.front().length()),
                boost::bind(&ClientConnection::handle_write, this,
                boost::asio::placeholders::error));
        }
    }
    else
    {
      std::err << "Error writting out message...\n";
      m_disconnected = true;
      m_server->DisconnectedClient (this);

    }
}

1voto

Sam Miller Punkte 23398

Bei der Erstellung von Anwendungen, die TCP-Byte-Streams verwenden, sendet der Sender in der Regel einen Header fester Länge, damit der Empfänger weiß, wie viele Bytes er zu erwarten hat. Dann liest der Empfänger diese Anzahl von Bytes und parst den resultierenden Puffer in ein XML-Objekt.

1voto

flamemyst Punkte 1117

Ich nehme an, Sie verwenden eine TCP-Verbindung. TCP ist ein Stream-Typ, daher können Sie nicht davon ausgehen, dass Ihr Paket in einem einzigen großen Paket ankommt. Sie müssen Ihr Kommunikationsdesign korrigieren, indem Sie wie bei der San-Miller-Antwort zuerst die Länge des Pakets senden oder ein Flag oder Trennzeichen senden, nachdem alle XML-Daten gesendet wurden.

0voto

Pat Mustard Punkte 1832

Wenn Sie davon ausgehen, dass Sie auf jeden Fall einige Daten auf dem Socket haben, den Sie löschen wollen, könnten Sie etwa so vorgehen:

void fulsh_socket()
{
    boost::asio::streambuf b;
    boost::asio::streambuf::mutable_buffers_type bufs = b.prepare(BUFFER_SIZE);
    std::size_t bytes = socket_.receive(bufs); // !!! This will block until some data becomes available
    b.commit(bytes);
    boost::asio::socket_base::bytes_readable command(true);
    socket_.io_control(command); 

    while(command.get())
    {
        bufs = b.prepare(BUFFER_SIZE);
        bytes = socket_.receive(bufs);
        b.commit(bytes);
        socket_.io_control(command); // reset for bytes pending
    }
    return;
}

donde socket_ ist eine Mitgliedsvariable.

HTH

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X