上传文件到亚马逊云盘报12030(ERROR_WINHTTP_CONNECTION_ERROR)

Instance 发布于 2016/02/16 11:20
阅读 385
收藏 0

我用winhttp协议,和亚马逊提供的网盘开发者接口写的上传文件示例,在上传小文件时,能正常上传,上传大文件时,在WinHttpWriteData处报12030错误,求大神提供解决方法。

示例代码如下:

// WinhttpUploadTest.cpp : 定义控制台应用程序的入口点。
 
#include "stdafx.h"
#include <vector>
#include <string>
#include <stdio.h>
#include <Windows.h>
#include <shlwapi.h>
#include <atlstr.h>
#include <cassert>
#include "Mime.h"
#include "conv.h"
#include "StringTool.h"
#include "WinHttpA.h"
#include <atlconv.h>
#pragma comment(lib,"winmm.lib")
using namespace std;


CString m_filepath, m_filename;
void BrowseToSelectFile()
{
OPENFILENAME  ofn;
wchar_t strFile[MAX_PATH];
memset(strFile, 0, sizeof(strFile));
memset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrFile = strFile;
ofn.nMaxFile = MAX_PATH;
if (GetOpenFileName(&ofn))
{
m_filepath = ofn.lpstrFile;
PathStripPath(strFile);
}
m_filename = strFile;
};


string _QueryContentLength(HINTERNET hRequest);
bool GetStatusCode(HINTERNET m_hRequest, DWORD&status_code);
CString boundary_part = L"--MULTI-PARTS-FORM-DATA-BOUNDARY";
LPCWSTR pszData = L"Winhttp Test";
HINTERNET hSession = NULL;
HINTERNET hConncet = NULL;
HINTERNET hRequest = NULL;


int m_nResolveTimeout = 2*60000;
int m_nConnectTimeout = 60000;
int m_nSendTimeout = 2*60000;
int m_nReceiveTimeout = 2*60000;






DWORD Write(char *buffer, DWORD size);
#define  SEND_BUF_SIZE 10*1024
CStringA outstr;
string content_size;
string token;


  DWORD WINAPI ProgressState(LPVOID lpvoid);
  CString GetTime();


  struct FileInfo
  {
 INT fileSize;
 INT sendSize;
 bool bError;
  };
  DWORD servert1, servert2;
  DWORD circlet1, circlet2;
int _tmain(int argc, _TCHAR* argv[])
{
BrowseToSelectFile();
CString request_body;
CString access_token = "Authorization: Bearer Atza|IQEBLjAsAhRKkD1b6cIN4hUm5cTSgxtOqFLXLgIUQkHDAKX-iqt8agI0AJtel1iEI8DtKs_JlAb2KL4usj8SjQHbGvIPcq7AsgevHchAmbtSi_1yuKiEm7atcym_u9Pe5v4vRZGfGm1qi9D1u01vGsbLYZs7pO6lFtyA1EmOKPPucQ7mkXQjAnW0zDVlL1hqMFWqHnKrH80VFEINqdZPvnuU3P0WNXT-WtwksFef8FQLTMiR5uQjHFqHShl-CwlWS75JPT6h0DwlIaUAjxSKpkJLGKrofGkpJAHBo6gQj9g96aXfC8VDtB6mN2lOVRR71vJ5gQybGEdjaaYp3XuBsklPXqL48_FgUTJc4EbOJE6kHTuc7WITVeBw7iJwzZ5OLV1actnNUSz_CRYsBTW8U7lLw75bz6KDW1w850-XbqREk0ukpnfGQmuySkslWFMF5nze";
access_token += L"\r\n";
CString content_type;
content_type.Format(_T("Content-Type: multipart/form-data; boundary=%s"), boundary_part);
content_type += L"\r\n";


//Content-length
CString carriageReturn("\r\n");


 


   CString m_strBlockStart = "--";
   m_strBlockStart += boundary_part;
m_strBlockStart += "\r\n";


CString m_strBlockEnd = "\r\n--";
m_strBlockEnd += boundary_part;
m_strBlockEnd += "--\r\n";


  request_body += m_strBlockStart;
  CString metadata;
  metadata.Format(_T("{\"name\": \"%s\",\"kind\":\"FILE\"}"), m_filename);
  metadata += _T("\r\n");
  
  CString body(L"Content-Disposition: form-data; name=\"metadata\"");//metadata
  body += "\r\n\r\n";
  request_body += body;
  request_body += metadata;




request_body += m_strBlockStart;


CString body1;
//body1.Format(L"Content-Disposition: form-data; name=\"file\";filename=%s", m_filename);//content
body1.Format(L"Content-Disposition: form-data; name=\"content\";filename=%s", m_filename);
body1 += L"\r\n";
CString body2;
LPCSTR type;
request_body += body1;
CMime::GetTypeFromPath(m_filepath, type);

body2.Format(L"Content-Type: %s", MB2WC(type).c_str());
body2 += L"\r\n\r\n";

request_body += body2;


//计算上传文件的大小
CStringTool ct;
UINT file_size = 0;
 
HANDLE file = CreateFile(m_filepath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
if (file == INVALID_HANDLE_VALUE)
{
printf("打开文件失败\n");
system("pause");
}


file_size = GetFileSize(file,NULL);
SetFilePointer(file, 0, NULL, FILE_BEGIN);






//建立请求
hSession = WinHttpOpen(NULL, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);


if (FALSE == WinHttpSetTimeouts(hSession, m_nResolveTimeout, m_nConnectTimeout, m_nSendTimeout, m_nSendTimeout))
{
printf("设置超时失败:%d\n", GetLastError());
system("pause");
}


string strUrl = "https://content-cn.drive.amazonaws.com/cdproxy/nodes";
//string strUrl = "http://192.168.0.165/wb/test.php";// 
string strHostName;
string strUrlPath;
string strExtraInfo;
int nPort;
WinHttpCrackUrlA_(strUrl,strHostName,strUrlPath,strExtraInfo,nPort);



if (hSession)
hConncet = WinHttpConnectA(hSession, strHostName.c_str(),nPort, 0);
else
{
printf("建立连接失败:%d\n",GetLastError());
system("pause");
}


DWORD request_flags = WINHTTP_FLAG_REFRESH | WINHTTP_FLAG_ESCAPE_PERCENT | WINHTTP_FLAG_SECURE;


if (hConncet)
hRequest = WinHttpOpenRequestA(hConncet, "POST", strUrlPath.c_str(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, request_flags);
else
{
printf("创建请求失败:%d\r\n", hRequest);
system("pause");
}
 
    //token = ct.CStringToMChar(access_token);
//添加请求头
CString start_time = GetTime();
bool bResult = false;
if (hRequest)
bResult = WinHttpAddRequestHeaders(hRequest, access_token, access_token.GetLength(), WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
if (!bResult)
{
printf("WinHttpAddRequestHeadersA faile,error:%d\n", GetLastError());
system("pause");
}


bResult = WinHttpAddRequestHeaders(hRequest, content_type, content_type.GetLength(), WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
if (!bResult)
{
printf("WinHttpAddRequestHeadersA faile,error:%d\n", GetLastError());
system("pause");
}


UINT body_lenth = 0;
 
CT2A bodydata(request_body, CP_UTF8);


//LPCSTR bodydata = ct.CStringToMChar(request_body);
 
int a = strlen(bodydata);
int b = m_strBlockEnd.GetLength();


LPCSTR end_part = ct.CStringToMChar(m_strBlockEnd);



body_lenth = strlen(bodydata) + file_size + m_strBlockEnd.GetLength()/*+ strlen(carriage)*/;


printf("Requestbody:\n%s\n", bodydata);
printf("file_size:%d\n", file_size);
servert1 = timeGetTime();
if (bResult)
bResult = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, body_lenth, 0);
else
{
printf("WinHttpSendRequest failed,error: %d\n", GetLastError());
system("pause");
}
if (!bResult)
{
printf("send body_length failed,error:%d\n", GetLastError());
system("pause");
}
DWORD dwWrittrn;





// if (!WinHttpWriteData(hRequest, carriage, strlen(carriage), &dwWrittrn))
// {
// int error = GetLastError();
// printf("WinHttpWriteData: %d\n", error);
// system("pause");
// }
 


if (!WinHttpWriteData(hRequest, bodydata, strlen(bodydata), &dwWrittrn))
{
servert2 = timeGetTime();
printf("服务器响应时间差:%d\n",servert2 - servert1);
int error = GetLastError();
printf("WinHttpWriteData: %d\n", error);
system("pause");
}


char buffer[SEND_BUF_SIZE] = {0};
//再向服务器写要上传的文件数据


DWORD size_send = 0;
FileInfo file_info;
file_info.fileSize = file_size;
file_info.sendSize = 0;
file_info.bError = false;
HANDLE hProgressThreat = CreateThread(0, 0, ProgressState,&file_info, NULL, NULL);
Sleep(1000);
while (size_send < file_size)
{
circlet1 = timeGetTime();
DWORD buf_size = 0;
//从文件流中读取一个缓冲区大小的数据
memset(buffer, 0, SEND_BUF_SIZE);
   INT size = ReadFile(file, buffer, SEND_BUF_SIZE, &buf_size, 0);

//printf("data:%s\n", buffer);
if (buf_size == 0)
{
TRACE_W(_T("未从输入流中读取到数据"));
break;
}


DWORD size_written = 0;


if (!WinHttpWriteData(hRequest, buffer, buf_size, &size_written))
{
int errValue = GetLastError();
TRACE_W(_T("WinHttpWriteData failed, error:%d"), errValue);
file_info.bError = true;
system("pause");
}


if (size_written == 0)
break;


size_send += size_written;
file_info.sendSize = size_send;
circlet2 = timeGetTime();
printf("循环时间差:%d ms\n", circlet2 - circlet1);
}
printf("size_send:%d\n", size_send);
//send end boundary
DWORD dwWrite = 0;
LPCSTR end_boudary = ct.CStringToMChar(m_strBlockEnd);
if (!WinHttpWriteData(hRequest, (LPVOID)end_boudary, strlen(end_boudary), &dwWrite))
{
int errValue = GetLastError();
TRACE_W(_T("WinHttpWriteData failed, error:%d"), errValue);
file_info.bError = true;
system("pause");
}
printf("%s\n", end_boudary);
bResult = WinHttpReceiveResponse(hRequest, NULL);
if (!bResult)
printf("Error %d has occured.\n", GetLastError());
DWORD dwSize = 0;
LPCTSTR lpOutBuffer = NULL;


if (bResult)
{
WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, NULL,
&dwSize, WINHTTP_NO_HEADER_INDEX);


// Allocate memory for the buffer.
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
lpOutBuffer = new TCHAR[dwSize+1];


memset((void*)lpOutBuffer, 0 , dwSize + 1);
// Now, use WinHttpQueryHeaders to retrieve the header.
bResult = WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX,
(LPVOID)lpOutBuffer, &dwSize, WINHTTP_NO_HEADER_INDEX);
}
}


printf("lpOutBuffer:%s\n", ct.CStringToMChar(lpOutBuffer));


delete[] lpOutBuffer;
// content_size = _QueryContentLength(hRequest);


dwSize = 0;
DWORD read_bytes = 0;
LPSTR pszOutBuffer = nullptr;
do
{
dwSize = 0;
if (!WinHttpQueryDataAvailable(hRequest, &dwSize))break;
if (!dwSize)break;
pszOutBuffer = new char[dwSize + 1]();
if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &read_bytes))
{
printf("Error &u in WinHttpReadData.\n", GetLastError());
return 0;
}


} while (dwSize > 0);


CString end_time = GetTime();


printf("start_time:%s\n", start_time);
printf("end_time:%s\n", end_time);


printf("lpOutBuffer:%s\n", ct.CStringToMChar(pszOutBuffer));
delete[] pszOutBuffer;


if (hRequest) WinHttpCloseHandle(hRequest);
if (hConncet) WinHttpCloseHandle(hConncet);
if (hSession) WinHttpCloseHandle(hSession);
CloseHandle(file);


getchar();
return 0;
}




string _QueryContentLength(HINTERNET hRequest)
{
std::string strContentLength;


DWORD dwSize = 0;
LPVOID lpOutBuffer = NULL;
BOOL bResults = FALSE;
do {
WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_LENGTH,WINHTTP_HEADER_NAME_BY_INDEX, NULL,
&dwSize, WINHTTP_NO_HEADER_INDEX);
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 
{
lpOutBuffer = new char[dwSize];
memset(lpOutBuffer, 0, dwSize);
// Now, use WinHttpQueryHeaders to retrieve the header.
bResults = WinHttpQueryHeaders(hRequest,
WINHTTP_QUERY_CONTENT_LENGTH,
WINHTTP_HEADER_NAME_BY_INDEX,
lpOutBuffer, &dwSize,
WINHTTP_NO_HEADER_INDEX);
}
} while (0);
if (lpOutBuffer) 
{
if (bResults) 
{
strContentLength.append((char*)lpOutBuffer, dwSize);
}
delete[] lpOutBuffer;
lpOutBuffer = NULL;
}
return strContentLength;
}


DWORD Write(char *buffer,DWORD size)
{
outstr.Append((LPCSTR)buffer, size);
return size;
}


bool GetStatusCode(HINTERNET m_hRequest, DWORD&status_code) 
{
status_code = 0;


if (!m_hRequest)
return false;
DWORD dwSize = 0;


WinHttpQueryHeaders(m_hRequest, WINHTTP_QUERY_STATUS_CODE, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &dwSize, WINHTTP_NO_HEADER_INDEX);
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
//wchar_t *szHeader = new wchar_t[dwSize]();
char szHeader[MAX_PATH] = { 0 };
WinHttpQueryHeaders(m_hRequest, WINHTTP_QUERY_STATUS_CODE, WINHTTP_HEADER_NAME_BY_INDEX, szHeader, &dwSize, WINHTTP_NO_HEADER_INDEX);
status_code = atoi(szHeader);
//delete[] szHeader;
}
else
{
printf("查询状态码失败:%d", GetLastError());
return false;
}


return true;
}


DWORD WINAPI ProgressState(LPVOID lpvoid)
{
FileInfo  *info = (FileInfo *)lpvoid;
while (true)
{
float percent = (float)info->sendSize *100/ info->fileSize;
printf("进度:%.2f\n", percent);
if (percent >= 100)
{
printf("100 %\n");
break;
}
if (info->bError)
{
break;
}
Sleep(1000);

}
return 0;
}


CString GetTime()
{
CString time_info;
SYSTEMTIME st;
GetLocalTime(&st);
time_info.Format(_T("(%d-%02d-%02d %02d:%02d:%02d)\r\n"),st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
return time_info;
}


加载中
返回顶部
顶部