使用完成端口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;}
分享到:
相关推荐
这份代码是我博客里的文章《完成端口详解 - 手把手教你玩转网络编程系列之三》的配套代码 里面的代码包括VC++2008/VC++2010编写的完成端口服务器端的代码,还包括一个对服务器端进行压力测试的客户端,都是经过我...
完成端口示例代码,包括用于测试的客户端代码。 是PiggyXP写的,大家可以配合PiggyXP的博客一起看 博客地址: http://blog.csdn.net/piggyxp/article/details/6922277 ps.我看了PiggyXP该资源下载得分已经超过上限...
完成端口,下载文件的代码。用vs2015实现,想了解完成端口的可以学习了结一下。下载步骤包括:登录-》版本验证-》有新版本就下载,没有新版本就不下载,已经下载了也不下载,登录失败也不下载。
完成端口编程的一个例子,创建端口,接收数据的服务器端例子代码
IOCP完成端口模型源代码 使用IOCP的TCP服务器使用过程大体如下: 1) 使用CreateIoCompletionPort函数创建完成端口,并以该I/O完成端口为参数创建多个服务线程; 2) 创建监听套接字; 3) 接收客户端连接请求,...
使用WOINSOCK 完成端口模型实现具有规模的服务器端和客户段,该代码封装了缓冲区的管理,和基本锁的处理.对新手使用完成端口模型是很好的借鉴和帮助.代码中可能存在一些BUG,在下乐意各位的修正和讨论.EMAIL:wanlijun...
老外写的一个管理完成端口C++源代码,很值得借鉴。里面有文档和例子程序。
一个完整的完成端口的例子代码。很好的学习资料。
应广大朋友要求,这份代码是我博客里的文章《完成端口详解 - 手把手教你玩转网络编程系列之三》的配套代码的客户端部分
4. 创建IO完成端口,将socket绑定到IO完成端口上 5. 根据当前机器CPU个数创建工作者线程池 6. 使用AcceptEx()提前创建客户socket,创建个数与CPU个数相关 以上准备工作全部完成 7. 工作者线程池 ...
关于理解完成端口详解的代码
一个简单的完成端口(服务端客户端)类源代码 更多资源请访问http://www.59186618.com
完成端口示例代码:IOCPExample_By_PiggyXP.rar
基于完成端口实现的windows服务器源代码。