2012-02-24 27 views
8

Tôi đang cố gắng viết khung hình jpeg thông qua một ổ cắm cho khách hàng sử dụng async_write(). Tôi đã sử dụng ví dụ tăng asynchronous TCP daytime server làm điểm bắt đầu.boost :: asio :: async_write, ghi dữ liệu lớn hơn 65536 byte

#include <ctime> 
#include <iostream> 
#include <string> 
#include <boost/bind.hpp> 
#include <boost/shared_ptr.hpp> 
#include <boost/enable_shared_from_this.hpp> 
#include <boost/asio.hpp> 

using boost::asio::ip::tcp; 

std::string make_daytime_string() 
{ 
    using namespace std; // For time_t, time and ctime; 
    time_t now = time(0); 
    return ctime(&now); 
} 

class tcp_connection 
    : public boost::enable_shared_from_this<tcp_connection> 
{ 
public: 
    typedef boost::shared_ptr<tcp_connection> pointer; 

    static pointer create(boost::asio::io_service& io_service) 
    { 
    return pointer(new tcp_connection(io_service)); 
    } 

    tcp::socket& socket() 
    { 
    return socket_; 
    } 

    void start() 
    { 
    message_ = make_daytime_string(); 

    boost::asio::async_write(socket_, boost::asio::buffer(message_), 
     boost::bind(&tcp_connection::handle_write, shared_from_this(), 
      boost::asio::placeholders::error, 
      boost::asio::placeholders::bytes_transferred)); 
    } 

private: 
    tcp_connection(boost::asio::io_service& io_service) 
    : socket_(io_service) 
    { 
    } 

    void handle_write(const boost::system::error_code& /*error*/, 
     size_t /*bytes_transferred*/) 
    { 
    } 

    tcp::socket socket_; 
    std::string message_; 
}; 

class tcp_server 
{ 
public: 
    tcp_server(boost::asio::io_service& io_service) 
    : acceptor_(io_service, tcp::endpoint(tcp::v4(), 13)) 
    { 
    start_accept(); 
    } 

private: 
    void start_accept() 
    { 
    tcp_connection::pointer new_connection = 
     tcp_connection::create(acceptor_.io_service()); 

    acceptor_.async_accept(new_connection->socket(), 
     boost::bind(&tcp_server::handle_accept, this, new_connection, 
      boost::asio::placeholders::error)); 
    } 

    void handle_accept(tcp_connection::pointer new_connection, 
     const boost::system::error_code& error) 
    { 
    if (!error) 
    { 
     new_connection->start(); 
     start_accept(); 
    } 
    } 

    tcp::acceptor acceptor_; 
}; 

int main() 
{ 
    try 
    { 
    boost::asio::io_service io_service; 
    tcp_server server(io_service); 
    io_service.run(); 
    } 
    catch (std::exception& e) 
    { 
    std::cerr << e.what() << std::endl; 
    } 

    return 0; 
} 

tôi đã sửa đổi phương pháp mà thực hiện async_write() như sau:

void start() 
    { 
    // fileToVector method reads contents of file to vector; 
    std::vector<unsigned char> message_ = fileToVector("/tmp/test"); 

    boost::asio::async_write(socket_, boost::asio::buffer(message_), 
     boost::bind(&tcp_connection::handle_write, shared_from_this(), 
      boost::asio::placeholders::error, 
      boost::asio::placeholders::bytes_transferred)); 
    } 

Khi đọc một file lớn từ máy chủ sử dụng một khách hàng, máy chủ sẽ chỉ viết tối đa là 65536 byte. Nếu tôi thay thế cuộc gọi boost::asio::async_write() bằng cuộc gọi đồng bộ boost::asio::write(), số lượng byte chính xác sẽ được chuyển cho khách hàng.

Vì vậy, tôi cho rằng câu hỏi của mình là, làm cách nào để gửi hơn 65536 byte bằng cách sử dụng boost::asio::async_write()? Mọi sự trợ giúp sẽ rất được trân trọng.

Trả lời

9

Một vấn đề là sử dụng dữ liệu chức năng async_write sẽ được gửi không ngay lập tức bằng chức năng nhưng trong một số thời gian sau khi phương pháp start được hoàn thành và biến message_ địa phương sẽ bị phá hủy và boost::asio::buffer không sao chép nội dung của message_. Nó chỉ lưu trữ một tham chiếu đến nó. Kết quả là không thể đoán trước. Có thể truyền tải 65536 byte là kết quả của hành vi này.

+0

Cũng thả bạn chú ý đến ví dụ của [link] (http://www.boost.org/doc/libs/1_48_0/doc/html/boost_asio/example/windows/transmit_file.cpp) của transmit_file ASIO. Sử dụng chức năng Windows 'TransmitFile' hoặc 'sendfile' trong Linux có thể tránh được việc cấp phát bộ đệm. – megabyte1024

+2

Vấn đề là chính xác như bạn mô tả, bộ đệm đã bị phá hủy trước khi async_write hoàn thành. Cảm ơn rất nhiều cho câu trả lời và câu trả lời. –

Các vấn đề liên quan