【问题标题】:Send POST data via HttpOpenRequestA通过 HttpOpenRequestA 发送 POST 数据
【发布时间】:2020-12-27 20:20:01
【问题描述】:

我正在尝试将我的 PC 名称发送到我的本地服务器并将其保存在一个文件中。

这是我的代码:

#include <stdio.h>
#include <windows.h>
#include <iostream>
#include <fstream>
#include <string>
#include <string.h>
#include <cstring>
#include <Lmcons.h>
#include <unistd.h>
#include <stdlib.h>
#include <WinInet.h>
#include <bits/stdc++.h>
#pragma comment( lib,"Wininet.lib")
using namespace std;

int main() {
    TCHAR name [ UNLEN + 1 ];
    DWORD size = UNLEN + 1;
    static CHAR hdrs[] = "Content-Type: application/x-www-form-urlencoded";
    if (GetUserName( (TCHAR*)name, &size ));
    static CHAR frmdata[] = "data=", name;

    HINTERNET hSession = InternetOpenA("http generic", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    HINTERNET hConnect = InternetConnect(hSession, "127.0.0.1", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
    HINTERNET hRequest = HttpOpenRequestA(hConnect, "POST", "/test/index.php", NULL, NULL, NULL, 0, 1);
    HttpSendRequestA(hRequest, hdrs, strlen(hdrs), frmdata, strlen(frmdata));
}

我也尝试过使用static CHAR frmdata[] = "data=" + name;,但不起作用。 这是我收到的错误:

错误:'const char [6]' 和 'TCHAR [257] {aka char [257]}' 类型的无效操作数到二进制 'operator+'|

【问题讨论】:

    标签: c++ sockets winapi wininet


    【解决方案1】:

    你需要连接,std::string 可以为你做。您还应该使用相同的基本字符类型以避免额外的转换。

    char name [ UNLEN + 1 ];
    DWORD size = UNLEN + 1;
    GetUserNameA( name, &size );
    std::string frmdata;
    frmdata += "data=";
    frmdata += name;
    
    ...
    
    HttpSendRequestA(hRequest, hdrs, strlen(hdrs), frmdata.data(), (DWORD)frmdata.size());
    

    如果您想传输 unicode 数据(在这种情况下使用 std::wstring),您需要将数据字符串转换为正确的 utf-8(查找 WideCharToMultiByte)。

    【讨论】:

    • 感谢您的回答,我试过了,我得到了这个error: error: invalid conversion from 'const void*' to 'LPVOID {aka void*}' [-fpermissive]|
    • std::string::c_str() 返回const char*HttpSendRequestA() 的第四个参数采用非常量 void*。因此,您需要一个非常量 char*,您可以通过丢弃 const 来获得它,例如:const_cast&lt;char*&gt;(frmdata.c_str()),或者直接使用 &amp;frmdata[0],或者在 C++17 及更高版本中使用 frmdata.data() .
    【解决方案2】:

    您不能像您尝试做的那样连接 char[] 数组。分配足够大小的单独缓冲区并将输入字符串复制到其中,例如:

    #include <windows.h>
    #include <Lmcons.h>
    #include <WinInet.h>
    #include <cstring>
    //#include <cstdio>
    using namespace std;
    
    #pragma comment( lib, "Wininet.lib")
    
    int main()
    {
        static char hdrs[] = "Content-Type: application/x-www-form-urlencoded";
    
        char name[UNLEN + 1] = {};
        DWORD size = UNLEN + 1;
        GetUserNameA(name, &size);
    
        char frmdata[5 + UNLEN + 1] = {};
        strcpy(frmdata, "data=");
        strcat(frmdata, name);
        // alternatively:
        // sprintf(frmdata, "data=%s", name);
    
        HINTERNET hSession = InternetOpenA("http generic", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
        if (!hSession) {
            // error handling...
        }
    
        HINTERNET hConnect = InternetConnectA(hSession, "127.0.0.1", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
        if (!hConnect) {
            // error handling...
        }
    
        HINTERNET hRequest = HttpOpenRequestA(hConnect, "POST", "/test/index.php", NULL, NULL, NULL, 0, 1);
        if (!hRequest) {
            // error handling...
        }
    
        if (!HttpSendRequestA(hRequest, hdrs, strlen(hdrs), frmdata, strlen(frmdata))) {
            // error handling...
        }
    
        InternetCloseHandle(hRequest);
        InternetCloseHandle(hConnect);
        InternetCloseHandle(hSession);
    
        return 0;
    }
    

    或者,您可以使用单个缓冲区,只需将其放大,并让GetUserNameA() 填充其中的一部分,然后您就不需要制作副本,例如:

    int main()
    {
        ...
    
        char frmdata[5 + UNLEN + 1] = "data=";
        DWORD size = UNLEN + 1;
        GetUserNameA(&frmdata[5], &size);
    
        ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-08
      • 1970-01-01
      • 1970-01-01
      • 2016-03-11
      • 2012-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多