boost::asio::streambuf 基本用法和注意事项

简介:

streamsize  sgetn(char_type *store,streamsize n)    返回缓冲区下n个字符并存储到store中,并将缓冲区位置后移n个字节


代码说明:本来是想不断的通过sgetn函数获取到streambuf的内容,由于没有完全理解sgetn获取流的方式,导致了问题的产生

int Teststreambuf()

{

boost::asio::streambuf request;

std::ostream request_stream(&request);

request_stream << "GET /cs/restfull/operationRestfullApi/testGet/ HTTP/1.1\r\n";

request_stream << "Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*\r\n";

request_stream << "Accept-Language: zh-CN\r\n";

request_stream << "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; InfoPath.3)\r\n";

request_stream << "Host: " << "192.168.0.88:8080" << "\r\n";

request_stream << "Connection: Keep-Alive\r\n\r\n";

//当第一次使用sgetn函数的时候,已经将所有的数据读完,指向流的结束位置

char buf[1024] = { 0 };

int len = request.size();

request.sgetn(buf, len);

//当第二次使用sgetn函数的时候,由于第一次函数调用指向了流的结束位置,

//所以第二次读取到的buf1是空的

char buf1[1024] = { 0 };

int len1 = request.size();

request.sgetn(buf1, len1);

return 0;

}


实际的测试环境:希望组装完成一次HTTP请求之后,循环发送构建的数据包,达到压力测试的结果,但是在接收端只是接收到一次的数据,初步怀疑是服务器的代码有问题,后面才发现是sgetn函数的使用方法有问题


#include <iostream>

#include <fstream>

#include <string>

#include <boost/asio.hpp>


using namespace std;

using namespace boost::asio;



int Teststreambuf()

{

io_service iosev;

ip::tcp::socket socket(iosev);

ip::tcp::endpoint ep(ip::address_v4::from_string("127.0.0.1"), 7002);

boost::system::error_code ec;

socket.connect(ep, ec);

if (ec) return -1;


boost::asio::streambuf request;

std::ostream request_stream(&request);

request_stream << "POST /cs/restfull/operationRestfullApi/testPost HTTP/1.1\r\n";

request_stream << "Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*\r\n";

request_stream << "Accept-Language: zh-CN\r\n";

request_stream << "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; InfoPath.3)\r\n";

request_stream << "Host: " << "192.168.0.88:8080" << "\r\n";

request_stream << "Connection: Keep-Alive\r\n\r\n";



while (1)

{

//第一次调用write之后,request的数据已经发送完毕,作为一个流,已经指向数据的末尾,所以

//当再次循环的时候发送的数据len==0,本意是循环发送上面的HTTP数据,对服务器进行压力测试

size_t len = boost::asio::write(socket, request);

std::cout << len << std::endl;

::Sleep(300);

}

return 0;

}



修改之后的代码

#include <iostream>

#include <fstream>

#include <string>

#include <boost/asio.hpp>


using namespace std;

using namespace boost::asio;



int Teststreambuf()

{

io_service iosev;

ip::tcp::socket socket(iosev);

ip::tcp::endpoint ep(ip::address_v4::from_string("127.0.0.1"), 7002);

boost::system::error_code ec;

socket.connect(ep, ec);

if (ec) return -1;


boost::asio::streambuf request;

std::ostream request_stream(&request);

request_stream << "POST /cs/restfull/operationRestfullApi/testPost HTTP/1.1\r\n";

request_stream << "Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*\r\n";

request_stream << "Accept-Language: zh-CN\r\n";

request_stream << "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; InfoPath.3)\r\n";

request_stream << "Host: " << "192.168.0.88:8080" << "\r\n";

request_stream << "Connection: Keep-Alive\r\n\r\n";


//跟上面的不一样的做法,是将request的数据一次性读取到buf数组中,然后循环发送buf的数据内容

  char buf[1024] = { 0 };

  request.sgetn(buf, request.size());


while (1)

{

size_t len = boost::asio::write(socket, boost::asio::buffer(buf));

std::cout << len << std::endl;

::Sleep(300);

}

return 0;

}






     本文转自fengyuzaitu 51CTO博客,原文链接:http://blog.51cto.com/fengyuzaitu/1954702,如需转载请自行联系原作者

相关文章
|
4月前
|
C语言 C++
boost库asio编译及配置
boost库asio编译及配置
119 0
|
6月前
19.4 Boost Asio 远程命令执行
命令执行机制的实现与原生套接字通信一致,仅仅只是在调用时采用了Boost通用接口,在服务端中我们通过封装实现一个`run_command`函数,该函数用于发送一个字符串命令,并循环等待接收客户端返回的字符串,当接收到结束标志`goodbye lyshark`时则说明数据传输完成则退出,客户端使用`exec_command`函数,该函数通过`_popen`函数执行一条命令,并循环`fgets`读取字符串发送给服务端,最终传输一个结束标志完成通信。
27 0
19.4 Boost Asio 远程命令执行
|
1月前
|
C++ Python
【boost】boost1.71安装以及VS2019调用boost.Python
【boost】boost1.71安装以及VS2019调用boost.Python
|
4月前
|
存储
boost 入门
boost 入门
38 0
|
9月前
|
存储 Windows
asio源码解析
基于1.57版本
147 0
asio源码解析
|
容器 编译器 C++
|
网络协议 编译器 消息中间件
|
安全 C++
asio 中strand的作用
[cpp] view plain copy    print? namespace   {       // strand提供串行执行, 能够保证线程安全, 同时被post或dispatch的方法, 不会被并发的执行.
1884 0