WinHttp的::WinHttpWriteData,GetLastError返回87(参数错误),求解

矫情狗_____ 2013-06-16 04:24:31
this->m_hRequest = ::WinHttpOpenRequest(this->m_hConnect, L"POST", L"/login", nullptr, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
if(!this->m_hRequest)
return false;

bRequest = ::WinHttpAddRequestHeaders(this->m_hRequest, L"Host: www.dropbox.com", (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD);
if(!bRequest) false;

bRequest = ::WinHttpAddRequestHeaders(this->m_hRequest, L"Connection: keep-alive", (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD);
if(!bRequest) false;

bRequest = ::WinHttpAddRequestHeaders(this->m_hRequest, L"Accept: text/html, application/xhtml+xml, */*", (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD);
if(!bRequest) return false;

bRequest = ::WinHttpAddRequestHeaders(this->m_hRequest, L"Accept-Encoding: gzip, deflate", (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD);
if(!bRequest) return false;

bRequest = ::WinHttpAddRequestHeaders(this->m_hRequest, this->_char2wchar(this->m_sCookie).c_str(), (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD);
if(!bRequest) return false;

bRequest = ::WinHttpSendRequest(this->m_hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
if(!bRequest) return false;

char psPost[1024] = {0};
sprintf(psPost, "t=%&lhs_type=default&display=desktop&login_email=1626086788@qq.com&login_password=********&login_submit=1&login_submit_dummy=%E7%99%BB%E5%BD%95", this->m_sToken);

DWORD dwByWritten = 0;
bRequest = ::WinHttpWriteData(this->m_hRequest, psPost, strlen(psPost), &dwByWritten);
DWORD nError = ::GetLastError(); //返回值为87

//求解到底哪里参数错误了...
...全文
349 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
有新工作否 2013-06-17
  • 打赏
  • 举报
回复
那就是验证有问题了呗,我以为你做实验,搞自己的网站呢。通不过很正常。
矫情狗_____ 2013-06-16
  • 打赏
  • 举报
回复
引用 10 楼 yudahai109 的回复:
[quote=引用 7 楼 stacksg 的回复:] [quote=引用 6 楼 yudahai109 的回复:] [quote=引用 2 楼 stacksg 的回复:] [quote=引用 1 楼 yudahai109 的回复:] 楼主,你的代码写的有问题呀,if(!bRequest) return false;????如果非真,应该直接结束程序吧,你这么多return false有什么用?非真,直接跳出程序,就知道哪一步错了。 看看微软给的例子 http://msdn.microsoft.com/en-us/library/windows/desktop/aa384120(v=vs.85).aspx 貌似这句 char psPost[1024] = {0}; sprintf(psPost, "t=%&lhs_type=default&display=desktop&login_email=1626086788@qq.com&login_password=********&login_submit=1&login_submit_dummy=%E7%99%BB%E5%BD%95", this->m_sToken); 应该放在WinHttpSendRequest 这个函数之前,不能为0噢。 看看微软的解释 dwTotalLength [in] An unsigned long integer value that contains the length, in bytes, of the total data sent. This parameter specifies the Content-Length header of the request. If the value of this parameter is greater than the length specified by dwOptionalLength, then WinHttpWriteData can be used to send additional data. dwTotalLength must not change between calls to WinHttpSendRequest for the same request. If dwTotalLength needs to be changed, the caller should create a new request.
我只是需要一步出错就放弃这个操作嘛[/quote] 晕死,当然需要了,一步出错,就结束程序呀,莫非你还让他继续运行不成?也不利于你检查错误呀。你每步都检查一下,然后单步执行,一下子就找到错误了。[/quote] 问题不在那,先不说return,那都是小事,我只是做测试.现在问题是WinHttpWriteData这个问题,这个接口返回FALSE,并且DWORD nerr = ::GetLastError(); nerr == 87; //代表参数错误.[/quote] (DWORD)strlen(psPost)转换一下试试,前面的都要转换。其他的我也想不到了。 但你最好把

char psPost[1024] = {0};
sprintf(psPost, "t=%&lhs_type=default&display=desktop&login_email=1626086788@qq.com&login_password=********&login_submit=1&login_submit_dummy=%E7%99%BB%E5%BD%95", this->m_sToken);
放在开头,然后把WinHttpSendRequest的参数修改一下,

WinHttpSendRequest(this->m_hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, (DWORD)strlen(psPost), 0)
因为我怀疑你WinHttpSendRequest和WinHttpWriteData的参数不一致导致的问题。你先这样做试试。 [/quote] 现在我把POST正文直接放到WinHttpSendRequest这里来了。但是引起了403。坑爹
有新工作否 2013-06-16
  • 打赏
  • 举报
回复
引用 7 楼 stacksg 的回复:
[quote=引用 6 楼 yudahai109 的回复:] [quote=引用 2 楼 stacksg 的回复:] [quote=引用 1 楼 yudahai109 的回复:] 楼主,你的代码写的有问题呀,if(!bRequest) return false;????如果非真,应该直接结束程序吧,你这么多return false有什么用?非真,直接跳出程序,就知道哪一步错了。 看看微软给的例子 http://msdn.microsoft.com/en-us/library/windows/desktop/aa384120(v=vs.85).aspx 貌似这句 char psPost[1024] = {0}; sprintf(psPost, "t=%&lhs_type=default&display=desktop&login_email=1626086788@qq.com&login_password=********&login_submit=1&login_submit_dummy=%E7%99%BB%E5%BD%95", this->m_sToken); 应该放在WinHttpSendRequest 这个函数之前,不能为0噢。 看看微软的解释 dwTotalLength [in] An unsigned long integer value that contains the length, in bytes, of the total data sent. This parameter specifies the Content-Length header of the request. If the value of this parameter is greater than the length specified by dwOptionalLength, then WinHttpWriteData can be used to send additional data. dwTotalLength must not change between calls to WinHttpSendRequest for the same request. If dwTotalLength needs to be changed, the caller should create a new request.
我只是需要一步出错就放弃这个操作嘛[/quote] 晕死,当然需要了,一步出错,就结束程序呀,莫非你还让他继续运行不成?也不利于你检查错误呀。你每步都检查一下,然后单步执行,一下子就找到错误了。[/quote] 问题不在那,先不说return,那都是小事,我只是做测试.现在问题是WinHttpWriteData这个问题,这个接口返回FALSE,并且DWORD nerr = ::GetLastError(); nerr == 87; //代表参数错误.[/quote] (DWORD)strlen(psPost)转换一下试试,前面的都要转换。其他的我也想不到了。 但你最好把

char psPost[1024] = {0};
sprintf(psPost, "t=%&lhs_type=default&display=desktop&login_email=1626086788@qq.com&login_password=********&login_submit=1&login_submit_dummy=%E7%99%BB%E5%BD%95", this->m_sToken);
放在开头,然后把WinHttpSendRequest的参数修改一下,

WinHttpSendRequest(this->m_hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, (DWORD)strlen(psPost), 0)
因为我怀疑你WinHttpSendRequest和WinHttpWriteData的参数不一致导致的问题。你先这样做试试。
矫情狗_____ 2013-06-16
  • 打赏
  • 举报
回复
引用 8 楼 henry3695 的回复:
引用 5 楼 stacksg 的回复:
那个是宽字符... [quote=引用 4 楼 henry3695 的回复:] 编码是不是有问题啊,把字符串前面的L去掉,是多字节编码吧
用多字节试试[/quote] 哥们,不是那里的问题,懂?
我看你有戏 2013-06-16
  • 打赏
  • 举报
回复
引用 5 楼 stacksg 的回复:
那个是宽字符...
引用 4 楼 henry3695 的回复:
编码是不是有问题啊,把字符串前面的L去掉,是多字节编码吧
用多字节试试
矫情狗_____ 2013-06-16
  • 打赏
  • 举报
回复
引用 6 楼 yudahai109 的回复:
[quote=引用 2 楼 stacksg 的回复:] [quote=引用 1 楼 yudahai109 的回复:] 楼主,你的代码写的有问题呀,if(!bRequest) return false;????如果非真,应该直接结束程序吧,你这么多return false有什么用?非真,直接跳出程序,就知道哪一步错了。 看看微软给的例子 http://msdn.microsoft.com/en-us/library/windows/desktop/aa384120(v=vs.85).aspx 貌似这句 char psPost[1024] = {0}; sprintf(psPost, "t=%&lhs_type=default&display=desktop&login_email=1626086788@qq.com&login_password=********&login_submit=1&login_submit_dummy=%E7%99%BB%E5%BD%95", this->m_sToken); 应该放在WinHttpSendRequest 这个函数之前,不能为0噢。 看看微软的解释 dwTotalLength [in] An unsigned long integer value that contains the length, in bytes, of the total data sent. This parameter specifies the Content-Length header of the request. If the value of this parameter is greater than the length specified by dwOptionalLength, then WinHttpWriteData can be used to send additional data. dwTotalLength must not change between calls to WinHttpSendRequest for the same request. If dwTotalLength needs to be changed, the caller should create a new request.
我只是需要一步出错就放弃这个操作嘛[/quote] 晕死,当然需要了,一步出错,就结束程序呀,莫非你还让他继续运行不成?也不利于你检查错误呀。你每步都检查一下,然后单步执行,一下子就找到错误了。[/quote] 问题不在那,先不说return,那都是小事,我只是做测试.现在问题是WinHttpWriteData这个问题,这个接口返回FALSE,并且DWORD nerr = ::GetLastError(); nerr == 87; //代表参数错误.
有新工作否 2013-06-16
  • 打赏
  • 举报
回复
引用 2 楼 stacksg 的回复:
[quote=引用 1 楼 yudahai109 的回复:] 楼主,你的代码写的有问题呀,if(!bRequest) return false;????如果非真,应该直接结束程序吧,你这么多return false有什么用?非真,直接跳出程序,就知道哪一步错了。 看看微软给的例子 http://msdn.microsoft.com/en-us/library/windows/desktop/aa384120(v=vs.85).aspx 貌似这句 char psPost[1024] = {0}; sprintf(psPost, "t=%&lhs_type=default&display=desktop&login_email=1626086788@qq.com&login_password=********&login_submit=1&login_submit_dummy=%E7%99%BB%E5%BD%95", this->m_sToken); 应该放在WinHttpSendRequest 这个函数之前,不能为0噢。 看看微软的解释 dwTotalLength [in] An unsigned long integer value that contains the length, in bytes, of the total data sent. This parameter specifies the Content-Length header of the request. If the value of this parameter is greater than the length specified by dwOptionalLength, then WinHttpWriteData can be used to send additional data. dwTotalLength must not change between calls to WinHttpSendRequest for the same request. If dwTotalLength needs to be changed, the caller should create a new request.
我只是需要一步出错就放弃这个操作嘛[/quote] 晕死,当然需要了,一步出错,就结束程序呀,莫非你还让他继续运行不成?也不利于你检查错误呀。你每步都检查一下,然后单步执行,一下子就找到错误了。
矫情狗_____ 2013-06-16
  • 打赏
  • 举报
回复
那个是宽字符...
引用 4 楼 henry3695 的回复:
编码是不是有问题啊,把字符串前面的L去掉,是多字节编码吧
我看你有戏 2013-06-16
  • 打赏
  • 举报
回复
编码是不是有问题啊,把字符串前面的L去掉,是多字节编码吧
矫情狗_____ 2013-06-16
  • 打赏
  • 举报
回复
引用 1 楼 yudahai109 的回复:
楼主,你的代码写的有问题呀,if(!bRequest) return false;????如果非真,应该直接结束程序吧,你这么多return false有什么用?非真,直接跳出程序,就知道哪一步错了。 看看微软给的例子 http://msdn.microsoft.com/en-us/library/windows/desktop/aa384120(v=vs.85).aspx 貌似这句 char psPost[1024] = {0}; sprintf(psPost, "t=%&lhs_type=default&display=desktop&login_email=1626086788@qq.com&login_password=********&login_submit=1&login_submit_dummy=%E7%99%BB%E5%BD%95", this->m_sToken); 应该放在WinHttpSendRequest 这个函数之前,不能为0噢。 看看微软的解释 dwTotalLength [in] An unsigned long integer value that contains the length, in bytes, of the total data sent. This parameter specifies the Content-Length header of the request. If the value of this parameter is greater than the length specified by dwOptionalLength, then WinHttpWriteData can be used to send additional data. dwTotalLength must not change between calls to WinHttpSendRequest for the same request. If dwTotalLength needs to be changed, the caller should create a new request.
而且申请栈内存前后没区别,因为我的token并没有再一次获取
矫情狗_____ 2013-06-16
  • 打赏
  • 举报
回复
引用 1 楼 yudahai109 的回复:
楼主,你的代码写的有问题呀,if(!bRequest) return false;????如果非真,应该直接结束程序吧,你这么多return false有什么用?非真,直接跳出程序,就知道哪一步错了。 看看微软给的例子 http://msdn.microsoft.com/en-us/library/windows/desktop/aa384120(v=vs.85).aspx 貌似这句 char psPost[1024] = {0}; sprintf(psPost, "t=%&lhs_type=default&display=desktop&login_email=1626086788@qq.com&login_password=********&login_submit=1&login_submit_dummy=%E7%99%BB%E5%BD%95", this->m_sToken); 应该放在WinHttpSendRequest 这个函数之前,不能为0噢。 看看微软的解释 dwTotalLength [in] An unsigned long integer value that contains the length, in bytes, of the total data sent. This parameter specifies the Content-Length header of the request. If the value of this parameter is greater than the length specified by dwOptionalLength, then WinHttpWriteData can be used to send additional data. dwTotalLength must not change between calls to WinHttpSendRequest for the same request. If dwTotalLength needs to be changed, the caller should create a new request.
我只是需要一步出错就放弃这个操作嘛
有新工作否 2013-06-16
  • 打赏
  • 举报
回复
楼主,你的代码写的有问题呀,if(!bRequest) return false;????如果非真,应该直接结束程序吧,你这么多return false有什么用?非真,直接跳出程序,就知道哪一步错了。 看看微软给的例子 http://msdn.microsoft.com/en-us/library/windows/desktop/aa384120(v=vs.85).aspx 貌似这句 char psPost[1024] = {0}; sprintf(psPost, "t=%&lhs_type=default&display=desktop&login_email=1626086788@qq.com&login_password=********&login_submit=1&login_submit_dummy=%E7%99%BB%E5%BD%95", this->m_sToken); 应该放在WinHttpSendRequest 这个函数之前,不能为0噢。 看看微软的解释 dwTotalLength [in] An unsigned long integer value that contains the length, in bytes, of the total data sent. This parameter specifies the Content-Length header of the request. If the value of this parameter is greater than the length specified by dwOptionalLength, then WinHttpWriteData can be used to send additional data. dwTotalLength must not change between calls to WinHttpSendRequest for the same request. If dwTotalLength needs to be changed, the caller should create a new request.
WinHTTP提供以下功能: WinHttpAddRequestHeaders 向HTTP请求句柄添加一个或多个HTTP请求标头。 WinHttpCheckPlatform 确定WinHTTP是否支持当前平台。 WinHttpCloseHandle 关闭单个 HINTERNET句柄。 WinHttpConnect 指定HTTP请求的初始目标服务器。 WinHttpCrackUrl 将URL分为其组成部分,例如主机名和路径。 WinHttpCreateProxyResolver 创建WinHttpGetProxyForUrlEx使用的句柄。 WinHttpCreateUrl 从组件部分创建URL,例如主机名和路径。 WinHttpDetectAutoProxyConfigUrl 查找代理自动配置(PAC)文件的URL。此功能报告PAC文件的URL,但不下载该文件。 WinHttpFreeProxyResult 释放从以前的调用WinHttpGetProxyResult检索的数据。 WinHttpGetDefaultProxyConfiguration 从注册表中检索默认的WinHTTP代理配置。 WinHTTPGetIEProxyConfigForCurrentUser 获取当前用户的Internet Explorer(IE)代理配置。 WinHttpGetProxyForUrl 检索指定URL的代理信息。 WinHttpGetProxyForUrlEx 检索指定URL的代理信息。 WinHttpGetProxyResult 检索到调用的结果WinHttpGetProxyForUrlEx。 WinHttpOpen 初始化应用程序对WinHTTP功能的使用。 WinHttpOpenRequest 创建HTTP请求句柄。 WinHttpQueryAuthSchemes 返回服务器支持的授权方案。 WinHttpQueryDataAvailable 返回可立即与读取数据的字节数 WinHttpReadDataWinHttpQueryHeaders 检索与HTTP请求相关联的头信息。 WinHttpQueryOption 在指定的句柄上查询Internet选项。 WinHttpReadDataWinHttpOpenRequest函数打开的句柄中读取数据 。 WinHttpReceiveResponse 结束由WinHttpSendRequest启动的HTTP请求 。 WinHttpResetAutoProxy 重置自动代理。 WinHttpSendRequest 将指定的请求发送到HTTP服务器。 WinHttpSetCredentials 将所需的授权凭证传递给服务器。 WinHttpSetDefaultProxyConfiguration 在注册表中设置默认的WinHTTP代理配置。 WinHttpSetOption 设置Internet选项。 WinHttpSetStatusCallback 设置WinHTTP可以在操作过程中进行调用的回调函数。 WinHttpSetTimeouts 设置涉及HTTP事务的各种超时。 WinHttpTimeFromSystemTime 根据HTTP版本1.0规范格式化日期和时间。 WinHttpTimeToSystemTime 获取HTTP时间/日期字符串并将其转换为 SYSTEMTIME结构。 WinHttpWriteData 将请求数据写入HTTP服务器。 WinHttpWebSocketClose 关闭WebSocket连接。 WinHttpWebSocketCompleteUpgrade 完成由WinHttpSendRequest启动的WebSocket握手。 WinHttpWebSocketQueryCloseStatus 获取服务器发送的关闭状态。 WinHttpWebSocketReceive 从WebSocket连接接收数据。 WinHttpWebSocketSend 通过WebSocket连接发送数据。 WinHttpWebSocketShutdown 向WebSocket连接发送关闭框架

64,662

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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