https的连接问题。

jcqstc 2005-12-08 01:26:51
下了一个连接https服务器的例子。是个SDK的工程,可以正常使用。
现在想做成多线程的,自己开了个MFC的工程,建立线程等等,都可以正常LINK。
但把例子里的main函数中的代码复制到进程函数中,就报这个错。

nresolved external symbol __imp__InternetConnectA@32
SSLCon.obj : error LNK2001: unresolved external symbol __imp__InternetOpenA@20
SSLCon.obj : error LNK2001: unresolved external symbol __imp__HttpSendRequestA@20
SSLCon.obj : error LNK2001: unresolved external symbol __imp__HttpOpenRequestA@32
SSLCon.obj : error LNK2001: unresolved external symbol __imp__CertCloseStore@8
SSLCon.obj : error LNK2001: unresolved external symbol __imp__CertFreeCertificateContext@4
SSLCon.obj : error LNK2001: unresolved external symbol __imp__InternetCloseHandle@4
SSLCon.obj : error LNK2001: unresolved external symbol __imp__InternetSetOptionA@16
SSLCon.obj : error LNK2001: unresolved external symbol __imp__CertOpenSystemStoreA@8
SSLCon.obj : error LNK2001: unresolved external symbol __imp__CertFindCertificateInStore@24
SSLCon.obj : error LNK2001: unresolved external symbol __imp__InternetReadFile@16
Release/httpsconnect.exe : fatal error LNK1120: 11 unresolved externals

求问题的原因和解决的办法。附录SSLCon这个类的代码:
// SSLCon.cpp: implementation of the CSslConnection class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SSLCon.h"
#include "WinInet.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSslConnection::CSslConnection()
{
m_hInternet = NULL;
m_hRequest = NULL;
m_certStoreType = certStoreMY;
m_hStore = NULL;
m_hSession = NULL;
m_pContext = NULL;
m_wPort = 443;
m_strAgentName = "";
m_secureFlags = INTERNET_FLAG_RELOAD|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_NO_CACHE_WRITE|
INTERNET_FLAG_SECURE|INTERNET_FLAG_IGNORE_CERT_CN_INVALID;
}

CSslConnection::~CSslConnection()
{
ClearHandles();
}


bool CSslConnection::ConnectToHttpsServer(string &strVerb)
{
try {
m_hInternet = InternetOpen(m_strAgentName.c_str(), INTERNET_OPEN_TYPE_PRECONFIG ,
NULL, NULL, 0);
if (!m_hInternet) {
m_strLastError = "Cannot open internet";
m_lastErrorCode = GetLastError();
return false;
}

m_hSession = InternetConnect(m_hInternet,
m_strServerName.c_str(),
m_wPort,
m_strUserName.c_str(),
m_strPassword.c_str(),
INTERNET_SERVICE_HTTP,
0,
0);
if (!m_hSession) {
m_strLastError = "Cannot connect to internet";
m_lastErrorCode = GetLastError();
ClearHandles();
return false;
}

}
catch(...) {
m_strLastError = "Memory Exception occured";
m_lastErrorCode = GetLastError();
return false;
}
return true;
}

bool CSslConnection::SendHttpsRequest()
{
try {
m_hRequest = HttpOpenRequest(m_hSession,
"POST",
m_strObjectName.c_str(),
NULL,
"",
NULL,
m_secureFlags,
m_ReqID);
if (!m_hRequest) {
m_strLastError = "Cannot perform http request";
m_lastErrorCode = GetLastError();
ClearHandles();
return false;
}

m_ReqID++;
for (int tries = 0; tries < 20; ++tries) {
int result = HttpSendRequest(m_hRequest, NULL, 0, NULL, 0);
if (result)
return true;
int lastErr = GetLastError();
if (lastErr == ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED) {
if (!SetClientCert()) {
m_strLastError = "Cannot perform http request, client authentication needed but couldnt detect required client certificate";
m_lastErrorCode = GetLastError();
return false;
}
}
else if (lastErr == ERROR_INTERNET_INVALID_CA) {
m_strLastError = "Cannot perform http request, client authentication needed, invalid client certificate is used";
m_lastErrorCode = GetLastError();
return false;
}
else {
m_strLastError = "Cannot perform http request";
m_lastErrorCode = GetLastError();
return false;
}
}
}
catch(...) {
m_strLastError = "Memory Exception occured";
m_lastErrorCode = GetLastError();
return false;
}
return false;
}

void CSslConnection::ClearHandles()
{
if (m_hInternet) {
InternetCloseHandle(m_hInternet);
m_hInternet = NULL;
}

if (m_hSession) {
InternetCloseHandle(m_hSession);
m_hSession = NULL;
}

if (m_pContext) {
CertFreeCertificateContext(m_pContext);
m_pContext = NULL;
}
if (m_hStore) {
CertCloseStore(m_hStore, CERT_CLOSE_STORE_FORCE_FLAG);
m_hStore = NULL;
}
}

bool CSslConnection::SetClientCert()
{
char *lpszStoreName;
switch (m_certStoreType) {
case certStoreMY:
lpszStoreName = "MY";
break;
case certStoreCA:
lpszStoreName = "CA";
break;
case certStoreROOT:
lpszStoreName = "ROOT";
break;
case certStoreSPC:
lpszStoreName = "SPC";
break;
}

m_hStore = CertOpenSystemStore(NULL, lpszStoreName);
if (!m_hStore) {
m_strLastError = "Cannot open system store ";
m_strLastError += lpszStoreName;
m_lastErrorCode = GetLastError();
ClearHandles();
return false;
}

m_pContext = FindCertWithOUNITName();

if (!m_pContext) {
m_strLastError = "Cannot find the required certificate";
m_lastErrorCode = GetLastError();
ClearHandles();
return false;
}

// INTERNET_OPTION_CLIENT_CERT_CONTEXT is 84
int res = InternetSetOption(m_hRequest,
INTERNET_OPTION_CLIENT_CERT_CONTEXT,
(void *) m_pContext, sizeof(CERT_CONTEXT));
if (!res) {
m_strLastError = "Cannot set certificate context";
m_lastErrorCode = GetLastError();
ClearHandles();
return false;
}

return true;
}

PCCERT_CONTEXT CSslConnection::FindCertWithOUNITName()
{
//This function performs a certificate contex search
//by the organizational unit name of the issuer
//Take this function as a sample for your possible different search functions
PCCERT_CONTEXT pCertContext = NULL;
CERT_RDN certRDN;

certRDN.cRDNAttr = 1;
certRDN.rgRDNAttr = new CERT_RDN_ATTR;
certRDN.rgRDNAttr->pszObjId = szOID_ORGANIZATIONAL_UNIT_NAME;
certRDN.rgRDNAttr->dwValueType = CERT_RDN_ANY_TYPE;
certRDN.rgRDNAttr->Value.pbData = (BYTE *) m_strOName.c_str();
certRDN.rgRDNAttr->Value.cbData = strlen(m_strOName.c_str());

pCertContext = CertFindCertificateInStore(m_hStore,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0, CERT_FIND_SUBJECT_STR, L"hsic", NULL);


delete certRDN.rgRDNAttr;
return pCertContext;
}

string CSslConnection::GetRequestResult()
{
DWORD dwNumberOfBytesRead;
char sz[1024];
string strResult;
int result;
do {
result = InternetReadFile(m_hRequest, sz, 1023, &dwNumberOfBytesRead);
sz[dwNumberOfBytesRead] = '\0';
int x = strlen(sz);
strResult += sz;
memset(sz, 0, 1024);

} while(result && dwNumberOfBytesRead != 0);
return strResult;
}
...全文
959 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
jcqstc 2005-12-08
  • 打赏
  • 举报
回复
问题解决,谢谢两位
oyljerry 2005-12-08
  • 打赏
  • 举报
回复
缺少对应的lib库文件
#pragma comment(lib,"Wininet.lib")
快乐鹦鹉 2005-12-08
  • 打赏
  • 举报
回复

#include "stdafx.h"
#include "SSLCon.h"
#include "WinInet.h"
后,增加#pragma comment(lib,"Wininet.lib")

原因是只引用了头文件#include "WinInet.h",没有引入相应的lib库文件。
另一个方法是在菜单:project->setting的link页面中的object/library modules项中输入Wininet.lib即可
jcqstc 2005-12-08
  • 打赏
  • 举报
回复
main函数的代码在这里:
CSslConnection inetSec;
string sAgentName("XXX");
string sServerName("XXX"); //Can be any https server address
string sUserName("");//if required
string sPass(""); //if required
string sObjectName("/XXX/test.jsp");//there should be an object to send a verb
string sQuery("user=X");

//You may choose any field of a certificate to perform a context search,
//i just implemented the OU field of the Issuer here
string sOrganizationUnitName("h");
//end
string strVerb = "GET";//My sample verb

inetSec.SetAgentName(sAgentName);
inetSec.SetCertStoreType(certStoreMY);
inetSec.SetObjectName(sObjectName);
//Sample field
inetSec.SetOrganizationName(sOrganizationUnitName);
//End

inetSec.SetPort(XXX);//443 is the default HTTPS port
inetSec.SetServerName(sServerName);

//you should better assign a unique number for each internet connection
inetSec.SetRequestID(0);
//end

if (!inetSec.ConnectToHttpsServer(strVerb)) {
cout << inetSec.GetLastErrorString() << " Code: " << inetSec.GetLastErrorCode();
return 0;
}

if (!inetSec.SendHttpsRequest()) {
cout << inetSec.GetLastErrorString() << " Code: " << inetSec.GetLastErrorCode();
return 0;
}


string response = inetSec.GetRequestResult();

cout << response.c_str() << endl;
sObjectName = "/XXX/test.jsp?user=X";
inetSec.SetObjectName(sObjectName);
if (!inetSec.SendHttpsRequest()) {
cout << inetSec.GetLastErrorString() << " Code: " << inetSec.GetLastErrorCode();
return 0;
}
response = inetSec.GetRequestResult();

cout << response.c_str() << endl;
快乐鹦鹉 2005-12-08
  • 打赏
  • 举报
回复
#pragma comment(lib,"Wininet.lib")

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧