使用完成端口HTTP下载的代码
2007-12-24 16:21
316 查看
使用完成端口HTTP下载的代码
(转载请注明来源于金庆的专栏)
试运行asio的async_client例程时,发现CPU占用很高,
所以又写了一个相同功能但直接调用完成端口API的代码,
进行比较,发现同样占用CPU。
与flashget比较,下载速度差不多,但flashget不占CPU。
将直接API调用代码和利用asio的代码都列在下面。
进行测试时,要将其中的参数定义改改,如SERVER参数。
并且要找个大文件下载才有明显结果。
#include <iostream>
#include <winsock2.h>
// Modify these:
// "http://server.test.com/jinq/test.zip"
#define SERVER "server.test.com"
#define REQ_PATH "/jinq/test.zip"
const char * SVR_IP = "127.0.0.1";
int main(int argc, char* argv[])
{
// Init.
WSADATA wsd;
WSAStartup(MAKEWORD(2, 2), &wsd);
HANDLE hCp = CreateIoCompletionPort(
INVALID_HANDLE_VALUE, NULL, 0, 0);
SOCKET skt = WSASocket(AF_INET,
SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
assert(INVALID_SOCKET != skt);
// connect skt and request
SOCKADDR_IN addr;
addr.sin_family = PF_INET;
addr.sin_port = htons(80);
addr.sin_addr.s_addr = inet_addr(SVR_IP);
connect(skt, (SOCKADDR*)&addr, sizeof(addr));
const char * REQ =
"GET " REQ_PATH " HTTP/1.0/r/n"
"Host: " SERVER "/r/n"
"Accept: */*/r/n"
"Connection: close/r/n/r/n";
send(skt, REQ, strlen(REQ), 0);
// Associate skt to completion port.
const DWORD COMPLETION_KEY = 12345;
CreateIoCompletionPort((HANDLE)skt,
hCp, COMPLETION_KEY, 0);
WSABUF wsaBuf;
wsaBuf.len = 64 * 1024 - 1;
wsaBuf.buf = new char[64 * 1024];
DWORD dwReceived;
DWORD dwFlags = 0;
WSAOVERLAPPED overlapped;
// Start recv.
ZeroMemory(&overlapped, sizeof(overlapped));
WSARecv(skt, &wsaBuf, 1,
&dwReceived,
&dwFlags,
&overlapped,
NULL);
// Check the completion port in loop.
while (true)
{
DWORD dwTransferred;
LPOVERLAPPED lpOverlapped;
DWORD dwKey;
BOOL bRet = GetQueuedCompletionStatus(
hCp, &dwTransferred, &dwKey, &lpOverlapped, 1000);
if (!bRet) continue;
assert(COMPLETION_KEY == dwKey);
std::cout << "Transferred: " << dwTransferred << std::endl;
assert(dwTransferred <= wsaBuf.len);
wsaBuf.buf[50] = '/0';
std::cout << "Content: " << wsaBuf.buf << std::endl;
// next recv
ZeroMemory(&overlapped, sizeof(overlapped));
WSARecv(skt, &wsaBuf, 1,
&dwReceived,
&dwFlags,
&overlapped,
NULL);
}
return 0;
}
#include <iostream>
#include <istream>
#include <ostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
const std::string SERVER("MyServer");
const std::string PATH("/jinq/test.zip");
using boost::asio::ip::tcp;
class client
{
public:
client(boost::asio::io_service& io_service,
const std::string& server, const std::string& path)
: socket_(io_service)
{
// Query server and try to connect.
tcp::resolver resolver(io_service);
tcp::resolver::query query(server, "http");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::resolver::iterator end;
// Try each endpoint until we successfully establish a connection.
boost::system::error_code error = boost::asio::error::host_not_found;
while (error && endpoint_iterator != end)
{
socket_.close();
socket_.connect(*endpoint_iterator++, error);
}
if (error)
throw boost::system::system_error(error);
// Send the request.
boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << "GET " << path << " HTTP/1.0/r/n";
request_stream << "Host: " << server << "/r/n";
request_stream << "Accept: */*/r/n";
request_stream << "Connection: close/r/n/r/n";
boost::asio::write(socket_, request);
// start reading...
boost::asio::async_read(socket_, response_,
boost::asio::transfer_at_least(1),
boost::bind(&client::handle_read_content, this,
boost::asio::placeholders::error));
}
private:
void handle_read_content(const boost::system::error_code& err)
{
if (!err)
{
// Write all of the data that has been read so far.
// std::cout << &response_ << "/n";
std::cout << "Received: " << response_.size() << std::endl;
response_.consume(response_.size());
// Continue reading remaining data until EOF.
boost::asio::async_read(socket_, response_,
boost::asio::transfer_at_least(1),
boost::bind(&client::handle_read_content, this,
boost::asio::placeholders::error));
}
else if (err != boost::asio::error::eof)
{
std::cout << "Error: " << err << "/n";
}
}
tcp::socket socket_;
boost::asio::streambuf response_;
};
int main(int argc, char* argv[])
{
try
{
boost::asio::io_service io_service;
client c(io_service, SERVER, PATH);
io_service.run();
}
catch (std::exception& e)
{
std::cout << "Exception: " << e.what() << "/n";
}
return 0;
}
(转载请注明来源于金庆的专栏)
试运行asio的async_client例程时,发现CPU占用很高,
所以又写了一个相同功能但直接调用完成端口API的代码,
进行比较,发现同样占用CPU。
与flashget比较,下载速度差不多,但flashget不占CPU。
将直接API调用代码和利用asio的代码都列在下面。
进行测试时,要将其中的参数定义改改,如SERVER参数。
并且要找个大文件下载才有明显结果。
#include <iostream>
#include <winsock2.h>
// Modify these:
// "http://server.test.com/jinq/test.zip"
#define SERVER "server.test.com"
#define REQ_PATH "/jinq/test.zip"
const char * SVR_IP = "127.0.0.1";
int main(int argc, char* argv[])
{
// Init.
WSADATA wsd;
WSAStartup(MAKEWORD(2, 2), &wsd);
HANDLE hCp = CreateIoCompletionPort(
INVALID_HANDLE_VALUE, NULL, 0, 0);
SOCKET skt = WSASocket(AF_INET,
SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
assert(INVALID_SOCKET != skt);
// connect skt and request
SOCKADDR_IN addr;
addr.sin_family = PF_INET;
addr.sin_port = htons(80);
addr.sin_addr.s_addr = inet_addr(SVR_IP);
connect(skt, (SOCKADDR*)&addr, sizeof(addr));
const char * REQ =
"GET " REQ_PATH " HTTP/1.0/r/n"
"Host: " SERVER "/r/n"
"Accept: */*/r/n"
"Connection: close/r/n/r/n";
send(skt, REQ, strlen(REQ), 0);
// Associate skt to completion port.
const DWORD COMPLETION_KEY = 12345;
CreateIoCompletionPort((HANDLE)skt,
hCp, COMPLETION_KEY, 0);
WSABUF wsaBuf;
wsaBuf.len = 64 * 1024 - 1;
wsaBuf.buf = new char[64 * 1024];
DWORD dwReceived;
DWORD dwFlags = 0;
WSAOVERLAPPED overlapped;
// Start recv.
ZeroMemory(&overlapped, sizeof(overlapped));
WSARecv(skt, &wsaBuf, 1,
&dwReceived,
&dwFlags,
&overlapped,
NULL);
// Check the completion port in loop.
while (true)
{
DWORD dwTransferred;
LPOVERLAPPED lpOverlapped;
DWORD dwKey;
BOOL bRet = GetQueuedCompletionStatus(
hCp, &dwTransferred, &dwKey, &lpOverlapped, 1000);
if (!bRet) continue;
assert(COMPLETION_KEY == dwKey);
std::cout << "Transferred: " << dwTransferred << std::endl;
assert(dwTransferred <= wsaBuf.len);
wsaBuf.buf[50] = '/0';
std::cout << "Content: " << wsaBuf.buf << std::endl;
// next recv
ZeroMemory(&overlapped, sizeof(overlapped));
WSARecv(skt, &wsaBuf, 1,
&dwReceived,
&dwFlags,
&overlapped,
NULL);
}
return 0;
}
#include <iostream>
#include <istream>
#include <ostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
const std::string SERVER("MyServer");
const std::string PATH("/jinq/test.zip");
using boost::asio::ip::tcp;
class client
{
public:
client(boost::asio::io_service& io_service,
const std::string& server, const std::string& path)
: socket_(io_service)
{
// Query server and try to connect.
tcp::resolver resolver(io_service);
tcp::resolver::query query(server, "http");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::resolver::iterator end;
// Try each endpoint until we successfully establish a connection.
boost::system::error_code error = boost::asio::error::host_not_found;
while (error && endpoint_iterator != end)
{
socket_.close();
socket_.connect(*endpoint_iterator++, error);
}
if (error)
throw boost::system::system_error(error);
// Send the request.
boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << "GET " << path << " HTTP/1.0/r/n";
request_stream << "Host: " << server << "/r/n";
request_stream << "Accept: */*/r/n";
request_stream << "Connection: close/r/n/r/n";
boost::asio::write(socket_, request);
// start reading...
boost::asio::async_read(socket_, response_,
boost::asio::transfer_at_least(1),
boost::bind(&client::handle_read_content, this,
boost::asio::placeholders::error));
}
private:
void handle_read_content(const boost::system::error_code& err)
{
if (!err)
{
// Write all of the data that has been read so far.
// std::cout << &response_ << "/n";
std::cout << "Received: " << response_.size() << std::endl;
response_.consume(response_.size());
// Continue reading remaining data until EOF.
boost::asio::async_read(socket_, response_,
boost::asio::transfer_at_least(1),
boost::bind(&client::handle_read_content, this,
boost::asio::placeholders::error));
}
else if (err != boost::asio::error::eof)
{
std::cout << "Error: " << err << "/n";
}
}
tcp::socket socket_;
boost::asio::streambuf response_;
};
int main(int argc, char* argv[])
{
try
{
boost::asio::io_service io_service;
client c(io_service, SERVER, PATH);
io_service.run();
}
catch (std::exception& e)
{
std::cout << "Exception: " << e.what() << "/n";
}
return 0;
}
相关文章推荐
- 使用完成端口HTTP下载的代码
- Windows 和 Linux下使用socket下载网页页面内容(可设置接收/发送超时)的代码(用socket解释http,不错)
- HttpWebRequest 下载网页Html代码 POST方式(站内使用了form方式) System.Net.WebException (417) Expectation failed
- ASP.NET 2.0 HttpHandler实现生成图片验证码(示例代码下载)
- Linux之git常用命令详解 2017-04-12 20:09:40 分类: LINUX 1.从远程仓库下载代码到本地 #git clone http://gitlab.xxx.com/xxx.g
- 演示事件(Event)怎样使用以及怎样为用户控件添加一个事件(示例代码下载)
- 使用CURL实现http文件下载加一个多任务的封装.
- 使用java实现http多线程断点下载文件(二)
- 使用HttpURLConnection实现文件下载
- 使用PHP自带zlib函数 几行代码实现PHP文件打包下载zip
- 简单实用的分页控件 AspNetPager.dll 下载地址、使用方法、含有代码示例
- sqlhelper 下载 使用指南 代码
- 在C++中使用sqlite的示例(从下载、编译、工程建立、配置、测试代码编写全方位介绍)
- iOS代码技巧之ASIHttpRequest类库的使用及Json解析(以解析中国天气网天气预报为例)
- git使用之如何将github库下载到本地与如何将代码上传github
- ASP.NET 2.0 HttpHandler实现生成图片验证码(示例代码下载)
- Flex与.NET互操作(五):使用FileReference+HttpHandler实现文件上传/下载
- ASP.NET 2.0 HttpHandler实现生成图片验证码(示例代码下载)
- Asp.net 2.0 自定义控件开发专题[详细探讨页面状态(视图状态和控件状态)机制及其使用场景](示例代码下载)
- 福利贴:使用线程池实现的Http上传下载实现