2012-02-24 19 views
8

से बड़ा डेटा लिखना मैं async_write() का उपयोग कर क्लाइंट को सॉकेट के माध्यम से जेपीईजी फ्रेम लिखने का प्रयास कर रहा हूं। मैंने शुरुआती बिंदु के रूप में asynchronous TCP daytime server उदाहरण को बढ़ावा दिया।boost :: asio :: async_write, 65536 बाइट्स

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

मैं विधि है कि async_write() इस प्रकार के रूप में प्रदर्शन को संशोधित किया है:

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

जब सर्वर एक ग्राहक का उपयोग करने से एक बड़ी फ़ाइल को पढ़ने, सर्वर केवल 65536 बाइट्स की एक अधिकतम लिखेंगे। यदि मैं सिंक्रोनस कॉल boost::asio::async_write() कॉल को प्रतिस्थापित करता हूं तो बाइट्स की सही मात्रा क्लाइंट को स्थानांतरित की जाती है।

तो मुझे लगता है कि मेरा सवाल है, मैं boost::asio::async_write() का उपयोग कर 65536 से अधिक बाइट कैसे भेज सकता हूं? किसी भी तरह की सहायता का स्वागत किया जाएगा।

उत्तर

9

एक मुद्दा यह है कि async_write समारोह डेटा का उपयोग कर के बाद start विधि समाप्त हो गया है और स्थानीय message_ चर नष्ट हो जाएगा और boost::asio::buffermessage_ की सामग्री की नकल नहीं करता समारोह द्वारा लेकिन कुछ समय में तुरंत नहीं भेज दिया जाएगा। यह केवल इसके लिए एक संदर्भ स्टोर करता है। नतीजा अप्रत्याशित है। 65536 बाइट्स का संचरण इस व्यवहार का परिणाम हो सकता है।

+0

आपको ट्रांसमिट_फाइल एएसआईओ के उदाहरण [लिंक] (http://www.boost.org/doc/libs/1_48_0/doc/html/boost_asio/example/windows/transmit_file.cpp) पर भी ध्यान दें। लिनक्स में 'ट्रांसमिटफाइल' विंडोज फ़ंक्शन या 'sendfile' का उपयोग करना बफर आवंटन ओवरहेड से बचने के लिए संभव है। – megabyte1024

+2

समस्या ठीक वही थी जैसा आपने वर्णन किया था, बफर को async_write पूरा होने से पहले नष्ट किया जा रहा था। उत्तर और उत्तर के लिए बहुत बहुत धन्यवाद। –

संबंधित मुद्दे