当前位置: 首页 > article >正文

MFC POST和Get

1.2、MFC发起HHTTP请求的基本发方法

用 CInternetSession 来发起 Http 请求,需要包含头文件:

#include <afxinet.h>

MFC 发起 HTTP 请求的逻辑,和用 WinINet 函数集 的整体过程类似,主要的步骤在 Steps in a Typical HTTP Client Application 有详细的描述。

1.3、用MFC发起HTTP GET请求

Get 服务类别,估计是 HTML 里最常用的,平时浏览网页用的就是这种。下面是用 GET 的方法来请求某个网页的内容,代码如下:

//通过 http GET 协议来获取并保存文件
CInternetSession session;
session.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, 1000 * 20);
session.SetOption(INTERNET_OPTION_CONNECT_BACKOFF, 1000);
session.SetOption(INTERNET_OPTION_CONNECT_RETRIES, 1);
 
CHttpConnection* pConnection = session.GetHttpConnection(TEXT("localhost"),(INTERNET_PORT)8080);
CHttpFile* pFile = pConnection->OpenRequest( CHttpConnection::HTTP_VERB_GET,
                                             TEXT("/Practice/index.jsp"));
 
CString szHeaders = L"Accept: audio/x-aiff, audio/basic, audio/midi,\
                     audio/mpeg, audio/wav, image/jpeg, image/gif, image/jpg, image/png,\
                     image/mng, image/bmp, text/plain, text/html, text/htm\r\n";
 
pFile->AddRequestHeaders(szHeaders);
 
pFile->SendRequest();
 
DWORD dwRet;
pFile->QueryInfoStatusCode(dwRet);
 
if(dwRet != HTTP_STATUS_OK)
{
    CString errText;
    errText.Format(L"POST出错,错误码:%d", dwRet);
    AfxMessageBox(errText);
}
else
{
    int len = pFile->GetLength();
    char buf[2000];
    int numread;
    CString filepath;
    CString strFile = L"response.txt";
    filepath.Format(L".\\%s", strFile);
    CFile myfile( filepath,
                  CFile::modeCreate|CFile::modeWrite|CFile::typeBinary);
    while ((numread = pFile->Read(buf,sizeof(buf)-1)) > 0)
    {
        buf[numread] = '\0';
        strFile += buf;
        myfile.Write(buf, numread);
    }
    myfile.Close();
}
 
session.Close();
pFile->Close(); 
delete pFile;

调试上面这段代码的时候,特别要注意以下几点:

  1. CHttpConnection::GetHttpConnection() 里第一参数,填写的应该是类似 www.yahoo.com 这样的根域名,如果带上 http:// 或是子路径,好像均会出错。
  2. CHttpFile::OpenRequest() 的第一个和第二个参数很重要,会影响是否能连接,尤其是第二个参数,要输入正确的 URI 路径;
  3. 在 CHttpFile::SendRequest() 之后,一定要用 CHttpFile::QueryInfoStatusCode() 来获得请求的状态码,从而判断是否正确获得了 http 数据;

Http 的状态码主要有以下几类:

Group     Meaning
200-299   Success
300-399   Information
400-499   Request error
500-599   Server error

更详细的代码参数:

Status code         Meaning
  200           URL located, transmission follows
  400           Unintelligible request
  404           Requested URL not found
  405           Server does not support requested method
  500           Unknown server error
  503           Server capacity reached

1.4、用MFC发起HTTP  POST请求

用 MFC 发起 HTTP Post 请求,主要流程和 MFC HTTP Get 代码一样,以下是示例代码:

//通过 http POST 协议来发送命令给服务器
CInternetSession session;
session.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, 1000 * 20);
session.SetOption(INTERNET_OPTION_CONNECT_BACKOFF, 1000);
session.SetOption(INTERNET_OPTION_CONNECT_RETRIES, 1);
 
CHttpConnection* pConnection = session.GetHttpConnection( TEXT("localhost"),
                                                          (INTERNET_PORT)8080);
CHttpFile* pFile = pConnection->OpenRequest( CHttpConnection::HTTP_VERB_POST,
                                             TEXT("/Practice/RequestObjectInJSP.jsp"),
                                             NULL,
                                             1,
                                             NULL,
                                             TEXT("HTTP/1.1"),
                                             INTERNET_FLAG_RELOAD);
 
//需要提交的数据
CString szHeaders   = L"Content-Type: application/x-www-form-urlencoded;";
 
//下面这段编码,则是可以让服务器正常处理
CHAR* strFormData = "username=WaterLin&password=TestPost";
pFile->SendRequest( szHeaders,
                    szHeaders.GetLength(),
                    (LPVOID)strFormData,
                    strlen(strFormData));
 
DWORD dwRet;
pFile->QueryInfoStatusCode(dwRet);
 
if(dwRet != HTTP_STATUS_OK)
{
    CString errText;
    errText.Format(L"POST出错,错误码:%d", dwRet);
    AfxMessageBox(errText);
}
else
{
    int len = pFile->GetLength();
    char buf[2000];
    int numread;
    CString filepath;
    CString strFile = L"result.html";
    filepath.Format(L".\\%s", strFile);
    CFile myfile(filepath,
        CFile::modeCreate|CFile::modeWrite|CFile::typeBinary);
    while ((numread = pFile->Read(buf,sizeof(buf)-1)) > 0)
    {
        buf[numread] = '\0';
        strFile += buf;
        myfile.Write(buf, numread);
    }
    myfile.Close();
}
 
session.Close();
pFile->Close(); 
delete pFile;

以上的代码,与 Get 对比起来,唯一的不同在于,提交 CHttpFile::SendRequest() 数据的时候,把表单的数据也带上了。

2、疑难杂症

2.1、字符编码,可恨的字符编码

对于 C/C++ 程序来说,最可恨的事情之一,莫过于字符集的问题了,尤其是在网络通信的时候,这一问题就显得更加让人恶心了

如果在用 MFC 发起 HTTP Post 请求时,你用的是宽字符集的编码,比如说,我把用 MFC 发起 HTTP Post 请求里同样的几行代码,替换成下面这几句:

CString szHeaders   = L"Content-Type: application/x-www-form-urlencoded;charset=UTF-8";
//下面这句,因为字符集的原因,是无法让服务器正常处理
CString strFormData = L"username=WaterLin&password=TestPost";
pFile->SendRequest( szHeaders,
                    szHeaders.GetLength(),
                    (LPVOID)(LPCTSTR)strFormData,
                    lstrlen(strFormData));
如果是,在服务器端会解析为如下这样:

<br>Parameters:u s e r n a m e
当你用文本编辑器打开返回的文件时,会显示如下的错误提示:

这个时候,虽然上面的 JSP 代码会输出

Character Encoding: null 
这样的值,但是服务器却会把表单内容当成 ISO-8859-1 字符集来处理,从而把表单参数解析为类似下面的怪胎:

看,这就是把字符集弄混了的下场!

则需要在 HTTP 报头里,一定要显式加上 charset=UTF-8 这样的约束,比如,在上面的代码,我就是直接这样写的:

CString szHeaders   = L"Content-Type: application/x-www-form-urlencoded;charset=UTF-8";
这样,服务器在收到你的报文时,就知道,你的 Form 表单内容,是用 UTF-8 来编码的,它也会用 UTF-8 字符集来解码你的 request,从而保证收到的消息一样。


http://www.kler.cn/a/380930.html

相关文章:

  • 安装CPU版的torch(清华源)
  • AIDD - 探索语言模型在药物分子生成方面的应用
  • CASA(Carnegie-Ames-Stanford Approach) 模型原理及实践
  • 负载均衡的原理
  • 【从零开始入门unity游戏开发之——C#篇21】C#面向对象的封装——`this`扩展方法、运算符重载、内部类、`partial` 定义分部类
  • 【Spring】Spring框架之-AOP
  • VSCode 上那些值得推荐的 CSS 插件
  • AIGC时代LaTeX排版的应用、技巧与未来展望
  • 高校大数据实训平台介绍
  • 学习虚幻C++开发日志——定时器
  • ai翻唱部分步骤
  • 3.5 windows xp ReactOS EiAllocatePool()
  • HarmonyOS 移动应用开发
  • C++学习笔记----10、模块、头文件及各种主题(一)---- 模块(4)
  • MFCC特征与Fbank特征在语音识别中的应用
  • Unity3D PCG地图的使用与优化详解
  • npm入门教程2:npm历史
  • AI 写作(一):开启创作新纪元(1/10)
  • Qt 文件目录操作
  • Linux 进程终止 进程等待
  • linux同步执行命令脚本 (xcall)
  • ubuntu工具 -- ubuntu服务器临时没有网络,急需联网下载东西怎么办? 使用手机提供网络
  • AI打造超写实虚拟人物:是科技奇迹还是伦理挑战?
  • 【Python爬虫实战】深入 Selenium:从节点信息提取到检测绕过的全攻略
  • 基于C语言实现的TCP客户端
  • 哈希表相关知识