网络服务器 - 发送较大的文件然后几个字节
我在发送较大的文件然后几个字节(即 700 字节)时遇到问题 由于某种原因,我可以下载一个比该文件更小的文件,但是当我尝试下载任何更大的文件时,它会在我的浏览器(Chrome)上告诉我 - 下载已停止 (即 251/700 B - 停止) 看起来它只下载了 251 个字节,然后停止了
这是我的代码: Web_Connection.h
#include <string>
#include <fstream>
#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;
class web_connection : public boost::enable_shared_from_this<web_connection>
{
public:
typedef boost::shared_ptr<web_connection> pointer;
static pointer create(boost::asio::io_service& io_service)
{
return pointer(new web_connection(io_service));
}
tcp::socket& socket()
{
return socket_;
}
void start()
{
std::filebuf *pbuf;
std::ifstream sourcestr;
long size;
char * buffer;
sourcestr.open("file-copy.exe",std::ios::in | std::ios::binary);
// get pointer to associated buffer object
pbuf=sourcestr.rdbuf();
// get file size using buffer's members
size=pbuf->pubseekoff (0,std::ios::end,std::ios::in);
pbuf->pubseekpos (0,std::ios::in);
// allocate memory to contain file data
buffer=new char[size];
// get file data
pbuf->sgetn (buffer,size);
// download file http headers
std::stringstream stream;
stream << "HTTP/1.0 200 OK\r\n"
"Content-Description: File Transfer\r\n"
"Content-Type: application/octet-stream\r\n"
"Content-Transfer-Encoding: binary\r\n"
"Content-Disposition: attachment; filename=file.exe\r\n"
"Expires: 0\r\n"
"Cache-Control: must-revalidate, post-check=0, pre-check=0'\r\n"
"Pragma: public\r\n"
"Content-Length: " << size << "\r\n\r\n";
message_ = stream.str();
message_.append(buffer, size);
/*message_ = "HTTP/1.0 200 OK\r\n"
"Content-Type: text/html\r\n\r\n";*/
boost::asio::async_write(socket_, boost::asio::buffer(message_),
boost::bind(&web_connection::handle_write, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
private:
web_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_;
};
Web Server.h
#include "web_connection.h"
class web_server
{
public:
web_server(unsigned short port)
{
try
{
acceptor_ = new tcp::acceptor(io_service, tcp::endpoint(tcp::v4(), port));
start_accept();
io_service.run();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}
~web_server()
{
delete acceptor_;
}
private:
void start_accept()
{
web_connection::pointer new_connection = web_connection::create(acceptor_->get_io_service());
acceptor_->async_accept(new_connection->socket(),
boost::bind(&web_server::handle_accept, this, new_connection,
boost::asio::placeholders::error));
}
void handle_accept(web_connection::pointer new_connection, const boost::system::error_code& error)
{
if (!error)
{
new_connection->start();
start_accept();
}
}
boost::asio::io_service io_service;
tcp::acceptor* acceptor_;
};
编辑: 我几乎通过设置这样的标题来解决这个问题:
stream << "HTTP/1.0 200 OK\r\n"
"Content-Description: File Transfer\r\n"
"Content-Type: application/octet-stream\r\n"
"Content-Transfer-Encoding: binary\r\n"
"Content-Disposition: attachment; filename=example.exe\r\n"
"Expires: 0\r\n"
"Cache-Control: must-revalidate, post-check=0, pre-check=0'\r\n"
"Pragma: public\r\n"
"Content-Length: " << size << "\r\n\r\n";
因为我的目标是下载exe文件..
但由于某种原因访问http://127.0.0.1:8080 并不总是下载文件 有时它向我展示同样的错误 最后一个错误: asyc_write抛出的错误代码:10054类别:系统 在我的浏览器上: (Chrome:Example.exe 536/542kb - Stoppd)
但是当我刷新页面几次时它终于可以工作了:S 我怎样才能让它始终工作?
I am having problem in sending larger files then few a bytes (i.e 700bytes)
for some reason i can download a file smaller then that but when im trying to download any bigger file its telling me on my browser (Chrome) - Download Stopped
(i.e 251/700 B - Stopped)
looks like it only download 251 bytes and then stopped
this is my code:
Web_Connection.h
#include <string>
#include <fstream>
#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;
class web_connection : public boost::enable_shared_from_this<web_connection>
{
public:
typedef boost::shared_ptr<web_connection> pointer;
static pointer create(boost::asio::io_service& io_service)
{
return pointer(new web_connection(io_service));
}
tcp::socket& socket()
{
return socket_;
}
void start()
{
std::filebuf *pbuf;
std::ifstream sourcestr;
long size;
char * buffer;
sourcestr.open("file-copy.exe",std::ios::in | std::ios::binary);
// get pointer to associated buffer object
pbuf=sourcestr.rdbuf();
// get file size using buffer's members
size=pbuf->pubseekoff (0,std::ios::end,std::ios::in);
pbuf->pubseekpos (0,std::ios::in);
// allocate memory to contain file data
buffer=new char[size];
// get file data
pbuf->sgetn (buffer,size);
// download file http headers
std::stringstream stream;
stream << "HTTP/1.0 200 OK\r\n"
"Content-Description: File Transfer\r\n"
"Content-Type: application/octet-stream\r\n"
"Content-Transfer-Encoding: binary\r\n"
"Content-Disposition: attachment; filename=file.exe\r\n"
"Expires: 0\r\n"
"Cache-Control: must-revalidate, post-check=0, pre-check=0'\r\n"
"Pragma: public\r\n"
"Content-Length: " << size << "\r\n\r\n";
message_ = stream.str();
message_.append(buffer, size);
/*message_ = "HTTP/1.0 200 OK\r\n"
"Content-Type: text/html\r\n\r\n";*/
boost::asio::async_write(socket_, boost::asio::buffer(message_),
boost::bind(&web_connection::handle_write, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
private:
web_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_;
};
Web Server.h
#include "web_connection.h"
class web_server
{
public:
web_server(unsigned short port)
{
try
{
acceptor_ = new tcp::acceptor(io_service, tcp::endpoint(tcp::v4(), port));
start_accept();
io_service.run();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}
~web_server()
{
delete acceptor_;
}
private:
void start_accept()
{
web_connection::pointer new_connection = web_connection::create(acceptor_->get_io_service());
acceptor_->async_accept(new_connection->socket(),
boost::bind(&web_server::handle_accept, this, new_connection,
boost::asio::placeholders::error));
}
void handle_accept(web_connection::pointer new_connection, const boost::system::error_code& error)
{
if (!error)
{
new_connection->start();
start_accept();
}
}
boost::asio::io_service io_service;
tcp::acceptor* acceptor_;
};
EDITED:
I managed almost to solve it by setting the headers like that:
stream << "HTTP/1.0 200 OK\r\n"
"Content-Description: File Transfer\r\n"
"Content-Type: application/octet-stream\r\n"
"Content-Transfer-Encoding: binary\r\n"
"Content-Disposition: attachment; filename=example.exe\r\n"
"Expires: 0\r\n"
"Cache-Control: must-revalidate, post-check=0, pre-check=0'\r\n"
"Pragma: public\r\n"
"Content-Length: " << size << "\r\n\r\n";
since my goal was to download exe file..
but for some reason accessing http://127.0.0.1:8080 not always downloading the file
sometimes its showing me the same error
Last Error:
Error code throwen by asyc_write: 10054 category: system
and on my browser:
(Chrome: Example.exe 536/542kb - Stoppd)
but when im refreshing the page few times it finally works :S
how can i make it always to work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论