链接器错误LNK2019在boost asio http客户端代码
Linker error LNK2019 in boost asio http client code
我正在尝试使用boost asio库实现http客户端。但我正面临一些链接错误,我无法修复。
代码
yql_asio.cpp
#include "common.h"
#include "yql.h"
int main(int argc, char* argv[])
{
try
{
int thread_num = 2;
if ( argc > 1 )
thread_num = boost::lexical_cast<int>(argv[1]);
boost::asio::io_service io_service;
Yql yql_main(io_service, "http://www.google.com");
yql_main.GetResponse();
io_service.run();
}
catch(std::exception & e)
{
std::cerr<<e.what()<<std::endl;
}
return 0;
}
yql.h
#ifndef YQL_H
#define YQL_H
#include "yql_conn.h"
#include "common.h"
typedef std::deque<io_service_ptr> ios_deque;
class Yql //: public boost::noncopyable
{
private:
std::string m_url;
std::string m_response;
//boost::shared_ptr<Connection> m_conn;
Connection *m_conn;
boost::asio::io_service &io_service_;
public:
Yql(boost::asio::io_service &io_service, std::string p_url);
~Yql(){}
void GetResponse();
};
#endif
yql.cpp
#include "yql.h"
Yql::Yql(boost::asio::io_service& io_services, std::string p_url)
: m_url(p_url)
, io_service_(io_services)
{
m_conn = new Connection(io_service_, p_url);
//m_conn = Connection::create(io_service_, m_url);
}
void Yql::GetResponse()
{
m_conn->start();
}
yql_conn.h
#ifndef YQL_CONN_H
#define YQL_CONN_H
#include "common.h"
#include <map>
class Connection //: public boost::enable_shared_from_this<Connection>
{
public:
typedef boost::shared_ptr<Connection> pointer;
static pointer create(ba::io_service & io_service, std::string p_url)
{
return pointer(new Connection(io_service, p_url));
}
Connection(ba::io_service & io_service, std::string p_url);
/*ba::ip::tcp::socket& socket()
{
return socket_;
} */
void start();
private:
/*void handle_browser_write(const bs::error_code & errc, size_t len);*/
void handle_read_headers(const bs::error_code & errc, size_t len);
void handle_server_write(const bs::error_code & errc, size_t len);
void handle_server_read_headers(const bs::error_code & errc, size_t len);
void handle_server_read_body(const bs::error_code & errc, size_t len);
void start_connect();
void start_write_to_server();
void shutdown();
void handle_resolve(const boost::system::error_code & err, ba::ip::tcp::resolver::iterator endpoint_iterator);
void handle_connect(const boost::system::error_code & err, ba::ip::tcp::resolver::iterator endpoint_iterator);
ba::io_service& io_service_;
ba::ip::tcp::socket socket_;
ba::ip::tcp::resolver resolver_;
//bool proxy_closed;
//bool isPersistent;
int32_t RespLen;
int32_t RespReaded;
//boost::array<char, 8192> bbuffer;
boost::array<char, 8192> sbuffer;
std::string m_response;
std::string m_url;
std::string m_headers;
std::string m_new_url;
std::string m_method;
std::string m_req_version;
std::string m_server;
std::string m_port;
//bool m_is_open;
std::string fReq;
typedef std::map<std::string, std::string> headersMap;
headersMap reqHeaders, respHeaders;
void parseHeaders(const std::string& h, headersMap& m);
};
#endif
yql_conn.cpp
#include "yql_conn.h"
Connection::Connection(ba::io_service & io_service, std::string p_url)
: io_service_(io_service)
, socket_(io_service)
, resolver_(io_service)
//, proxy_closed(false)
//, isPersistent(false)
//, m_is_open(false)
, m_url(p_url)
{
} //end of Connection()
void Connection::start() //called
{
std::cout<<__FUNCTION__<<"BEGINS"<<std::endl;
m_headers.clear();
reqHeaders.clear();
respHeaders.clear();
start_connect();
//boost::asio::async_read(bsocket_, ba::buffer(bbuffer), ba::transfer_at_least(1),
// boost::bind(&Connection::handle_browser_read_headers,
// shared_from_this(),
// ba::placeholders::error,
// ba::placeholders::bytes_transferred) );
std::cout<<__FUNCTION__<<"ENDS"<<std::endl;
} //start()
void Connection::start_connect() //called
{
std::cout<<__FUNCTION__<<"BEGINS"<<std::endl;
m_server = "";
//std::string port = "80";
m_port = "80";
boost::regex rHTTP("http://(.*?)(:(\d+))?(/.*)");
boost::smatch m;
if ( boost::regex_search(m_url, m, rHTTP, boost::match_extra) )
{
m_server = m[1].str();
if ( m[2].str() != "" )
{
m_port = m[3].str();
}
m_new_url = m[4].str();
}
if ( m_server.empty() )
{
std::cout<<"Can't parse URL "<<std::endl;
return;
}
//if ( !m_is_open || (server != m_server) || (port != m_port) )
/*if ( port != m_port) )
{
m_server = server;
m_port = port;
*/
boost::asio::ip::tcp::resolver::query query(m_server, m_port);
resolver_.async_resolve(query,
boost::bind(&Connection::handle_resolve, this,//shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::iterator));
//}
/*else
{
start_write_to_server();
}*/
std::cout<<__FUNCTION__<<"ENDS"<<std::endl;
}//start_connect()
void Connection::handle_resolve(const boost::system::error_code & err,
boost::asio::ip::tcp::resolver::iterator endpoint_iterator) //called
{
std::cout<<__FUNCTION__<<"BEGINS"<<std::endl;
if ( !err )
{
std::cout<<"Remote address resolved..."<<std::endl;
boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
socket_.async_connect(endpoint, boost::bind(&Connection::handle_connect,
//shared_from_this(),
this,
boost::asio::placeholders::error,
++endpoint_iterator));
}
else
{
shutdown();
}
std::cout<<__FUNCTION__<<"ENDS"<<std::endl;
} //handle_resolve()
void Connection::handle_connect(const boost::system::error_code & err,
boost::asio::ip::tcp::resolver::iterator endpoint_iterator) //called
{
std::cout<<__FUNCTION__<<"BEGINS"<<std::endl;
if ( !err )
{
boost::asio::ip::tcp::endpoint remote_host = socket_.remote_endpoint();
boost::asio::ip::address remote_host_addr = remote_host.address();
std::string addr_repr = remote_host_addr.to_string();
std::cout<<"Connected to "<<addr_repr<<std::endl;
//m_is_open = true;
start_write_to_server();
}
else if ( endpoint_iterator != boost::asio::ip::tcp::resolver::iterator())
{
socket_.close();
boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
socket_.async_connect(endpoint, boost::bind(&Connection::handle_connect,
//shared_from_this(),
this,
boost::asio::placeholders::error,
++endpoint_iterator));
}
else
{
shutdown();
}
std::cout<<__FUNCTION__<<"ENDS"<<std::endl;
} //handle_connect()
void Connection::start_write_to_server() //called
{
std::cout<<__FUNCTION__<<"BEGINS"<<std::endl;
fReq = m_method;
fReq += " ";
//fReq += m_new_url;
fReq += m_url;
fReq += " HTTP/";
fReq += "1.0";
fReq += "rn";
fReq += m_headers;
boost::asio::async_write(socket_, boost::asio::buffer(fReq),
boost::bind(&Connection::handle_server_write, this, //shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
m_headers.clear();
std::cout<<__FUNCTION__<<"ENDS"<<std::endl;
} //start_write_to_server()
void Connection::handle_server_write(const bs::error_code & err, size_t len) //called
{
std::cout<<__FUNCTION__<<"BEGINS"<<std::endl;
if ( !err )
{
std::cout<<"Bytes sent to server :: "<<len<<std::endl;
boost::asio::async_read(socket_, boost::asio::buffer(sbuffer), boost::asio::transfer_at_least(1),
boost::bind(&Connection::handle_server_read_headers,
//shared_from_this(),
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred ) );
}
else
{
shutdown();
}
std::cout<<__FUNCTION__<<"ENDS"<<std::endl;
} //handle_server_write
void Connection::handle_server_read_headers(const boost::system::error_code & err, size_t len) //called
{
std::cout<<__FUNCTION__<<"BEGINS"<<std::endl;
if ( !err )
{
std::string::size_type idx;
if ( m_headers.empty() )
m_headers = std::string(sbuffer.data(), len);
else
m_headers += std::string(sbuffer.data(), len);
idx = m_headers.find("rnrn");
if ( idx == std::string::npos )
{
boost::asio::async_read(socket_, boost::asio::buffer(sbuffer),
boost::asio::transfer_at_least(1),
boost::bind(&Connection::handle_read_headers,
//shared_from_this(),
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
RespReaded = len - idx - 4;
idx = m_headers.find("rn");
std::string respString = m_headers.substr(0, idx);
RespLen = -1;
parseHeaders(m_headers.substr(idx+2), respHeaders);
std::string reqConnString = "", respConnString = "";
std::string respVersion = respString.substr(respString.find("HTTP/")+5,3);
headersMap::iterator it = respHeaders.find("Content-Length");
if ( it != respHeaders.end() )
RespLen = boost::lexical_cast<int>(it->second);
it = respHeaders.find("Connection");
if ( it != respHeaders.end() )
respConnString = it->second;
it = respHeaders.find("Connection");
if ( it != respHeaders.end() )
reqConnString = it->second;
//isPersistent = (
// ((m_req_version == "1.1" && reqConnString != "close") ||
// (m_req_version == "1.0" && reqConnString == "keep-alive" )) &&
// ((respVersion == "1.1" && respConnString != "close") ||
// (respVersion == "1.0" && respConnString == "kepp-alive" )) &&
// RespLen != -1 );
std::cout<<"Header Received :: "<<m_headers;
boost::asio::async_read(socket_, boost::asio::buffer(sbuffer, len),
boost::asio::transfer_at_least(1),
boost::bind(&Connection::handle_server_read_body,
//shared_from_this(),
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
//boost::asio::async_write(bsocket_, boost::asio::buffer(m_headers),
// boost::bind(&Connection::handle_browser_write,
// shared_from_this(),
// boost::asio::placeholders::error,
// boost::asio::placeholders::bytes_transferred));
}
}
else
{
shutdown();
}
std::cout<<__FUNCTION__<<"ENDS"<<std::endl;
} //handle_server_read_headers
void Connection::handle_server_read_body(const bs::error_code & err, size_t len) //called
{
std::cout<<__FUNCTION__<<"BEGINS"<<std::endl;
if ( !err || err == boost::asio::error::eof )
{
std::cout<<"Data received :: "<<std::string(sbuffer.begin(), sbuffer.end())<<std::endl;
RespReaded += len;
boost::asio::async_read(socket_, boost::asio::buffer(sbuffer, len),
boost::asio::transfer_at_least(1),
boost::bind(&Connection::handle_server_read_body,
//shared_from_this(),
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
//if ( err == boost::asio::error::eof )
// proxy_closed = true;
//boost::asio::async_write(bsocket_, boost::asio::buffer(sbuffer, len),
// boost::bind(&Connection::handle_browser_write,
// shared_from_this(),
// boost::asio::placeholders::error,
// boost::asio::placeholders::bytes_transferred));
}
else
{
shutdown();
}
std::cout<<__FUNCTION__<<"ENDS"<<std::endl;
} //handle_server_read_body
void Connection::handle_read_headers(const bs::error_code & err, size_t len)
{
if (!err)
{
std::cout<<"Bytes Received ... :: "<<len<<std::endl;
if ( m_headers.empty())
{
m_headers = std::string(sbuffer.data(), len);
}
else
{
m_headers += std::string(sbuffer.data(), len);
}
if ( m_headers.find("rnrn") == std::string::npos )
{
boost::asio::async_read(socket_, ba::buffer(sbuffer), ba::transfer_at_least(1),
boost::bind(&Connection::handle_read_headers,
//shared_from_this(),
this,
ba::placeholders::error,
ba::placeholders::bytes_transferred));
}
else
{
std::string::size_type idx = m_headers.find("rn");
std::string reqString = m_headers.substr(0, idx);
m_headers.erase(0, idx+2);
idx = reqString.find(" ");
if ( idx == std::string::npos )
{
std::cout<<"Bad first line : "<<reqString<<std::endl;
return;
}
m_method = reqString.substr(0, idx);
reqString = reqString.substr(idx+1);
idx = reqString.find(" ");
if ( idx == std::string::npos )
{
std::cout<<"Bad first line of request : "<< reqString << std::endl;
return;
}
m_url = reqString.substr(0,idx);
m_req_version = reqString.substr(idx+1);
idx = m_req_version.find("/");
if ( idx == std::string::npos )
{
std::cout<<"Bad first line of request : "<<reqString<<std::endl;
return;
}
m_req_version = m_req_version.substr(idx+1);
parseHeaders(m_headers, reqHeaders);
//start_connect();
}
}
else
{
shutdown();
}
}
void Connection::parseHeaders(const std::string & h, headersMap & hm)
{
std::string str(h);
std::string::size_type idx;
std::string t;
while ( (idx=str.find("rn")) != std::string::npos )
{
t = str.substr(0, idx);
str.erase(0, idx+2);
if ( t == "" )
break;
idx = t.find(": ");
if ( idx == std::string::npos )
{
std::cout<<"Bad header line: "<<t<<std::endl;
break;
}
hm.insert(std::make_pair(t.substr(0, idx), t.substr(idx+2)));
}
} //parseHeaders
void Connection::shutdown()
{
std::cout<<"Closing socket..."<<std::endl;
socket_.close();
//bsocket_.close();
} //shutdown
构成
#ifndef COMMON_H
#define COMMON_H
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/regex.hpp>
#include <boost/bind.hpp>
#include <boost/thread/thread.hpp>
#include <iostream>
#include <string>
#include <boost/utility.hpp>
namespace ba=boost::asio;
namespace bs=boost::system;
typedef boost::shared_ptr<ba::ip::tcp::socket> socket_ptr;
typedef boost::shared_ptr<ba::io_service> io_service_ptr;
#endif
链接器错误
1>------ Rebuild All started: Project: yql_asio, Configuration: Debug Win32 ------
1>Build started 20-03-2013 AM 1:06:33.
1>InitializeBuildStatus:
1> Touching "Debugyql_asio.unsuccessfulbuild".
1>ClCompile:
1> stdafx.cpp
1> yql_conn.h
1> Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:
1> - add -D_WIN32_WINNT=0x0501 to the compiler command line; or
1> - add _WIN32_WINNT=0x0501 to your project's Preprocessor Definitions.
1> Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).
1> yql_conn.cpp
1> Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:
1> - add -D_WIN32_WINNT=0x0501 to the compiler command line; or
1> - add _WIN32_WINNT=0x0501 to your project's Preprocessor Definitions.
1> Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).
1> yql_asio.cpp
1> Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:
1> - add -D_WIN32_WINNT=0x0501 to the compiler command line; or
1> - add _WIN32_WINNT=0x0501 to your project's Preprocessor Definitions.
1> Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).
1> Yql.cpp
1> Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:
1> - add -D_WIN32_WINNT=0x0501 to the compiler command line; or
1> - add _WIN32_WINNT=0x0501 to your project's Preprocessor Definitions.
1> Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).
1> Generating Code...
1>Debugyql_conn.obj : warning LNK4042: object specified more than once; extras ignored
1>Yql.obj : error LNK2019: unresolved external symbol "public: __thiscall Connection::Connection(class boost::asio::io_service &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??0Connection@@QAE@AAVio_service@asio@boost@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function "public: __thiscall Yql::Yql(class boost::asio::io_service &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??0Yql@@QAE@AAVio_service@asio@boost@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
1>Yql.obj : error LNK2019: unresolved external symbol "public: void __thiscall Connection::start(void)" (?start@Connection@@QAEXXZ) referenced in function "public: void __thiscall Yql::GetResponse(void)" (?GetResponse@Yql@@QAEXXZ)
1>C:UsersasitDocumentsVisual Studio 2010Projectsyql_asioDebugyql_asio.exe : fatal error LNK1120: 2 unresolved externals
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:31.88
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
请帮我修复这个bug
您有两个LNK2019错误。第一个说它找不到两个参数的连接构造函数。第二个说它无法从连接类中找到start方法。还有一个LNK4042警告。此警告表明您已经意识到链接到Connection类(在yql_conn.h和yql_conn.cpp中定义)的问题,然后尝试显式链接到该文件。您的显式链接可能是正确的,但由于有两个版本浮动,它选择了另一个,并忽略了显式的一个。这就解释了为什么你会收到这个警告。
所以,我怀疑问题是版本控制之一,或者有另一个由其他人编写的连接类,您正在挑选。您可能在其他地方定义了连接类—在不同的文件中或相同的文件但在不同的文件夹中。该文件的旧版本可能没有正确定义Connection构造函数,也没有定义start方法——这将解释无法解析的链接错误。所以,你可以尝试去yql.h或yql.cpp右键单击Connection。选择转到定义。如果它将您带到具有start定义的文件,并且构造函数看起来正确,则尝试再次右键单击Connection并选择Find All References。您也可以尝试在所有文件中搜索连接。您可能需要删除旧文件并将新文件插入到项目中,或者您可以简单地将新文件中的代码复制并粘贴到项目正在使用的文件中,然后删除显式链接。
相关文章:
- 如何使用C++和Boost Asio从HTTP发布请求中获取键值
- 在C ++ ASIO中,如何为HTTP或HTTPS创建相同的套接字对象(接口/抽象问题?
- 断开连接后重新连接boost beast(asio)websocket和http连接时出错
- 我可以使用 Boost.Asio 和 Boost.Beast 库发出 HTTPS 请求或 HTTP/2 请求吗?
- Boost :: Asio HTTP帖子中的空身体
- 使用带有SSL(HTTPS)的Boost-Beast(ASIO)HTTP客户端
- 浏览器将随机HTTP消息正文发送到我的boost.asio服务器.我可以更改此设置吗?
- boost::asio http 服务器无法向 Postman 返回有效响应
- 为什么这C++ASIO,当执行HTTP / SSL请求时,BEAST服务器会进入错误状态
- Boost asio library for networking (http client)
- 基于BOOST :: ASIO-慢慢http客户端 - (转移块)
- 使用Fiddler拦截Boost.Asio HTTP/S请求
- boost::asio http客户端停止工作,我不知道为什么
- Boost ASIO HTTP client POST
- Boost::Asio HTTP服务器速度极慢
- Boost.Asio HTTP library
- 助推asio HTTP服务器,如何停止
- 为什么我的c++ Boost ASIO HTTP客户端返回不完整的响应
- 链接器错误LNK2019在boost asio http客户端代码
- 使用 helgrind 提升 asio http async_client示例警告:误报