I give up! I cannot for the life of me figure out buffers and streams. Any help is greatly appreciated. Here's what I have so far: filesize_ = fs::file_size(filepath_); std::ifstream file(filepath_.file_string().c_str(), std::ios::in ); file.seekg (file_offset_, std::ios::beg); //offset typically 0 unless resuming transfer //just trying this for fun boost::asio::ip::tcp::socket::send_buffer_size option; data_socket_.get_option(option); //tcp socket uint64_t size = option.value(); while (bytes_sent < filesize_) { //i test a file 21200678 bytes long. This tranfers anywhere from 21135097 to 21196000. bytes_sent += data_socket_.send(boost::asio::buffer(file.rdbuf(), std::min(size,filesize_-bytes_sent))); //this always transfers 21204202 bytes_sent += data_socket_.send(boost::asio::buffer(file.rdbuf(), size)); } data_socket_.close(); boost::asio::async_read_until(control_socket_, response_, "\r\n", boost::bind(&FTPClient::handleRead, this, boost::asio::placeholders::error)); write_some vs. send give same results. I've also tried something like: char buf[1024]; socket.write_some(buf, file.readsome(buf, 1024)); which deosnt read all the bytes. Sometimes if I check file.rdbuf()->in_avail(), it reports 0 using above method and bytes_sent stops growing about 99% of the way through. I tired setting the the socket linger option to true. No go. I tried making the data_socket a buffered_write_stream, same results. What am I doing wrong? Sometimes bytes_sent is exactly the file size, but the remote file size is slightly less. Maybe closing the socket stream too early? That sends an eof which the server responds to but it should arrive AFTER the data i would think... no clue. please help :) In the meantime, I'm going to go rip up some FSF ftp client code from source forge heh. Thanks Chris
Chris Fairles wrote:
while (bytes_sent < filesize_) { //i test a file 21200678 bytes long. This tranfers anywhere from 21135097 to 21196000. bytes_sent += data_socket_.send(boost::asio::buffer(file.rdbuf(), std::min(size,filesize_-bytes_sent)));
//this always transfers 21204202 bytes_sent += data_socket_.send(boost::asio::buffer(file.rdbuf(), size));
}
I don't see anything in this loop to consume the data from the ifstream.
What am I doing wrong? Sometimes bytes_sent is exactly the file size, but the remote file size is slightly less. Maybe closing the socket stream too early? That sends an eof which the server responds to but it should arrive AFTER the data i would think...
I can't say what's wrong with your iostream code, but as send() and write_some() can result in a "short send" (i.e. send fewer bytes than you ask it to) you might like to use asio::write() instead. Cheers, Chris
On 6/12/07, Christopher Kohlhoff
Chris Fairles wrote:
while (bytes_sent < filesize_) { //i test a file 21200678 bytes long. This tranfers anywhere from 21135097 to 21196000. bytes_sent += data_socket_.send(boost::asio::buffer(file.rdbuf(), std::min(size,filesize_-bytes_sent)));
//this always transfers 21204202 bytes_sent += data_socket_.send(boost::asio::buffer(file.rdbuf(), size));
}
I don't see anything in this loop to consume the data from the ifstream.
I'm not exactly sure what you mean by consume?
I can't say what's wrong with your iostream code, but as send() and write_some() can result in a "short send" (i.e. send fewer bytes than you ask it to) you might like to use asio::write() instead.
Well you were right about write(). I switched it up to this: char buf[64]; std::filebuf filebuf; filebuf.open(filepath_.file_string().c_str(), std::ios::in); filebuf.pubseekoff (file_offset_, std::ios::beg); //if need be uint32_t bytes_read = 0; while (bytes_sent < filesize_) { bytes_read = filebuf.sgetn(buf, 64); bytes_sent += boost::asio::write(data_socket_, boost::asio::buffer(buf, bytes_read)); } data_socket_.close(); //send eof and await response boost::asio::async_read_until(control_socket_, response_, "\r\n", boost::bind(&FTPClient::handleRead, this, boost::asio::placeholders::error)); and not only does it get the whole file each time, but about 100x faster. I will have to look into the difference between a tcp::socket's write(_some) and the free function write as I've used above. Thanks for your help. Chris
participants (2)
-
Chris Fairles
-
Christopher Kohlhoff