2010-07-27 42 views
1

我正在实现一个使用boost向客户端发送xml的服务器。我面临的问题是缓冲区不会立即发送并累积到一个点然后发送整个事情。这在我的客户端导致了一个问题,当它解析xml时,它可能有不完整的xml标记(不完整的消息)。有什么方法可以在需要发送消息时刷新套接字?以下是服务器的写入代码。如何使用boost刷新套接字

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

    } 
} 
+0

使服务器在第一个数据包中发送XML的大小。在客户端,读取并减少N(N是每次读取的字节数)。当值达到0时,XML已完成并准备好进行分析。 – jweyrich 2010-07-29 01:57:20

回答

1

通常,当使用TCP字节流创建应用程序时,发送者会发送一个固定长度的头,以便接收者知道需要多少个字节。然后接收器读取很多字节并将生成的缓冲区解析为一个XML对象。

1

我假设你正在使用TCP连接。 TCP是流类型的,所以你不能假设你的数据包会进入一个大包。您需要修复您的通信设计,通过像San Miller回复那样首先发送尺寸长度,或者在所有xml数据发送完毕后发送标志或分隔符。

0

假设你肯定会得到你想要清除插座上的一些数据,你可以做这样的事情:

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

其中socket_是一个成员变量。

HTH