c++ http通信使用CInternetSession整理

2 篇文章 0 订阅
1 篇文章 0 订阅

最近因为项目原因接触到http协议通信,边学边做,首先感谢

sunriver2000

大神封装好的类,可以直接调用接口进行通信,和源码对比着整理一下自己的收获

https://blog.csdn.net/sunriver2000/article/details/84670639

首先简单说明一下,当需要从服务器获取信息时候使用的是 “GET”,上传使用的是"POST"。

然后可以源码看到实际调用的是ExecuteRequest类

int CHttpClient::ExecuteRequest(int strMethod, LPCTSTR strUrl, LPCTSTR strPostData, CString &strResponse)  

其中

strMethod是方法 “GET”或者“POST”,

strUrl是地址,他应该是完整的,例“http://198.168.0.1::80/api/device/notify”

strPostData是要post上去的数据,当然GET的方法话是NULL

strResponse是服务器返回的数据;

然后用到AfxParaseURL函数分析strUrl字符串并返回其相应元素

AfxParseURL(strUrl, dwServiceType, strServer, strObject, nPort);  

 *分析 URL 字符串并返回类型及其元素
     *dwServiceType; 指示互联网服务的类型
     *strServer:接收待解析的URL服务器名
     *strObject: 接收待解析的URL 涉及的对象(可能为空)
     *nPort: 如果存在,则从URL的服务器或对象部分搜索出来
     *返回 如果URL是成功解析返回非0值
     *     如果URL为空的或不包含一个已知的Internet服务类型 返回0

例如“http://198.168.0.1::80/api/device/notify” 会分析出dwServiceType = AFX_INET_SERVICE_HTTP

strServer = 198.168.0.1,strObject = /api/device/notify,nPort = 80;

然后连接服务器,将strurl分析出来的元素填进去;

  m_pConnection = m_pSession->GetHttpConnection(strServer, dwServiceType == AFX_INET_SERVICE_HTTP ? NORMAL_CONNECT : SECURE_CONNECT, nPort);

确定连接使用的方法 ,和路径。在这里如果我们是访问要登录网站的话,需要自己填上cookies,服务类型必须声明 就是在dwServiceType | INTERNET_FLAG_NO_COOKIES,使用就是第一次strPostData里放置账号和密码,返回的信息里面包含了cookies,将cookies取出来,下次访问时候再添加进请求头里面,下面会讲到。

m_pFile = m_pConnection->OpenRequest(strMethod, strObject, NULL, 1, NULL, NULL, (dwServiceType == AFX_INET_SERVICE_HTTP ? NORMAL_REQUEST : 

 然后添加请求头信息

 m_pFile->AddRequestHeaders("Accept: */*,application/json");	
 m_pFile->AddRequestHeaders("Accept-Charset:UTF8");  
 m_pFile->AddRequestHeaders("Accept-Language: zh-cn;q=0.8,en;q=0.6,ja;q=0.4");  
 m_pFile->AddRequestHeaders("Content-Type:application/json");	

其中Content-Type:是根据发送的内容,如果发送的表单格式就要选择application/x-www-form-urlencoded

发送json格式 application/json

如果发送文件流就要选择multipart/form-data;boundary = ..

具体差别可以看这篇文章https://www.cnblogs.com/softidea/p/5745369.html

其中文件流的请求的一定要注意boundary分隔符 ,每个分隔符前面会多两短横线--,结束还会用一次分隔符 并且后面也加了两短横线--,示例

BASHPOST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA

------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"

title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png

PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

如果是要登录的网站,要加上cookies

就和上面一样

 m_pFile->AddRequestHeaders("Cookies: *******");	

接着就可以发送了,发送信息和信息长度,当然GET方法括号里面可以为空

 m_pFile->SendRequest(NULL, 0, (LPVOID)(LPCTSTR)strPostData, strPostData == NULL ? 0 : strlen(strPostData));  

 然后是判断访问成功没有,成功的话返回的dwRet值为200;

m_pFile->QueryInfoStatusCode(dwRet); 

再然后就是解析服务器返回的信息

m_pFile->ReadString(strUtf8);
strResponse = UTF8AndUnicode_Convert(strUtf8, CP_UTF8, CP_ACP);

 如果是要登录的网站,登录成功后返回一个cookie,这个cookie就可以添加进请求头执行下次访问

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中实现HTTP文件上传可以使用CInternetSession类和CHttpConnection类来建立HTTP连接,并使用OpenRequest方法打开连接。然后,可以使用AddRequestHeaders方法添加HTTP请求头,并使用SendRequestEx方法发送请求至HTTP服务器。使用CInternetFile的Write和WriteString方法可以发送文件数据至服务器。上传文件的大小可以通过计算协议头大小、数据描述字段字节大小、实际数据字节大小和协议尾大小来确定。最后,使用EndRequest方法关闭连接。以下是一个简单的C++代码示例: ```cpp #include <afxinet.h> void UploadFile(const CString& filePath, const CString& serverURL) { CInternetSession session; CHttpConnection* pConnection = session.GetHttpConnection(serverURL); if (pConnection) { CHttpFile* pFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST, _T("upload.php")); if (pFile) { CString fileName = filePath.Mid(filePath.ReverseFind('\\') + 1); CString contentType = _T("Content-Type: application/octet-stream\r\n"); CString contentDisposition = _T("Content-Disposition: form-data; name=\"file\"; filename=\"") + fileName + _T("\"\r\n"); CString endBoundary = _T("\r\n--BOUNDARY--\r\n"); CString headers = contentType + contentDisposition + endBoundary; DWORD headersLength = headers.GetLength(); DWORD fileSize = GetFileSize(filePath); DWORD totalRequestLength = headersLength + fileSize; CString requestHeaders; requestHeaders.Format(_T("Content-Length: %d\r\n"), totalRequestLength); pFile->SendRequestEx(requestHeaders, (LPVOID)(LPCTSTR)headers, headersLength, HSR_SYNC | HSR_INITIATE); pFile->WriteFile(filePath); pFile->EndRequest(); pFile->Close(); delete pFile; } pConnection->Close(); delete pConnection; } session.Close(); } ``` 请注意,这只是一个简单的示例代码,实际应用中可能需要根据具体需求进行修改和完善。 #### 引用[.reference_title] - *1* [C++实现HTTP上传](https://blog.csdn.net/srests/article/details/50751599)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [form表单上传文件C++开发后台服务,协议解析实操](https://blog.csdn.net/aflyeaglenku/article/details/51668673)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值