麻煩各位!
系統:Ubuntu 16.0.4, BOOST
先說問題:
1、設定為非阻塞,socket.connect(...)應該如何設定超時?物理斷網情況下,這里超時設定的不起作用;
2、第一boost::asio::read_until(...)超時可以正常獲取并處理,但是第二個和以后的read_until(...)非阻塞就讀不到資料了,要設定成阻塞才能讀取資料。我想問一下,這種情況下,我需要設定超時,后面的read_until(...)應該如何設定超時?
代碼如下:
int HttpCommandInterface::httpGet(const std::string request_path, std::string &header, std::string &content)
{
header = "";
content = "";
using boost::asio::ip::tcp;
try
{
boost::asio::io_service io_service;
// Lookup endpoint
tcp::resolver resolver(io_service);
tcp::resolver::query query(http_host_, std::to_string(http_port_));
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::resolver::iterator end;
// Create socket
tcp::socket socket(io_service);
boost::system::error_code error = boost::asio::error::host_not_found;
fd_set fdSelect;
struct timeval tvSocket;
boost::asio::socket_base::non_blocking_io io_option(true);
// Iterate over endpoints and etablish connection
while (error && endpoint_iterator != end)
{
socket.close();
tvSocket.tv_sec = 10;
tvSocket.tv_usec = 0;
socket.open(tcp::v4());
setsockopt(socket.native(), SOL_SOCKET, SO_RCVTIMEO, &tvSocket, sizeof(tvSocket));
setsockopt(socket.native(), SOL_SOCKET, SO_SNDTIMEO, &tvSocket, sizeof(tvSocket));
io_option.set(true);
socket.io_control(io_option); //全部設為不阻塞 用select來檢測
socket.connect(*endpoint_iterator++, error);
FD_ZERO(&fdSelect);
FD_SET(socket.native(), &fdSelect);
tvSocket.tv_sec = 10;
tvSocket.tv_usec = 0;
if (select(socket.native() + 1, NULL, &fdSelect, NULL, &tvSocket) <= 0 || !FD_ISSET(socket.native(), &fdSelect))
{
error = boost::asio::error::host_not_found;
}
else
{
error = boost::system::errc::make_error_code(boost::system::errc::success);
break;
}
}
if (error)
throw boost::system::system_error(error);
// Prepare request
boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << "GET " << request_path << " HTTP/1.0\r\n\r\n";
boost::asio::write(socket, request);
// Read the response status line. The response streambuf will automatically
// grow to accommodate the entire line. The growth may be limited by passing
// a maximum size to the streambuf constructor.
tvSocket.tv_sec = 10;
tvSocket.tv_usec = 0;
FD_ZERO(&fdSelect);
FD_SET(socket.native(), &fdSelect);
tvSocket.tv_sec = 10;
tvSocket.tv_usec = 0;
if (select(socket.native() + 1, &fdSelect, NULL, NULL, &tvSocket) <= 0 || !FD_ISSET(socket.native(), &fdSelect))
{
MYLOG_PRINT(wayToPrint, "RevTimeOut");
return 0;
}
boost::asio::streambuf response;
boost::asio::read_until(socket, response, "\r\n");
io_option.set(false); //到這里 再ifdown也不會讀也不會一直阻塞 必須要恢復阻塞 否則讀不了資料
socket.io_control(io_option);
// Check that response is OK.
std::istream response_stream(&response);
std::string http_version;
response_stream >> http_version;
unsigned int status_code;
response_stream >> status_code;
std::string status_message;
std::getline(response_stream, status_message);
if (!response_stream || http_version.substr(0, 5) != "HTTP/")
{
MYLOG_PRINT(wayToPrint, "Invalid response");
return 0;
}
// Read the response headers, which are terminated by a blank line.
boost::asio::read_until(socket, response, "\r\n\r\n");
// Process the response headers.
std::string tmp;
while (std::getline(response_stream, tmp) && tmp != "\r")
header += tmp + "\n";
// Write whatever content we already have to output.
while (std::getline(response_stream, tmp))
content += tmp;
// Read until EOF, writing data to output as we go.
while (boost::asio::read(socket, response, boost::asio::transfer_at_least(1), error))
{
response_stream.clear();
while (std::getline(response_stream, tmp))
content += tmp;
}
if (error != boost::asio::error::eof)
throw boost::system::system_error(error);
// Substitute CRs by a space
for (std::size_t i = 0; i < header.size(); i++)
if (header[i] == '\r')
header[i] = ' ';
for (std::size_t i = 0; i < content.size(); i++)
if (content[i] == '\r')
content[i] = ' ';
return status_code;
}
catch (std::exception &e)
{
MYLOG_PRINT(wayToPrint, "Exception: {}", e.what());
//std::cerr << "Exception: " << e.what() << std::endl;
return 0;
}
}
uj5u.com熱心網友回復:
有高人指點一下嗎?謝謝!轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/22674.html
標籤:應用程序開發區
