使用CHttpConnection实现图片上传

void UploadPic(CString strPicName, CString strIP, int nPort, CString strRemote)
{
	CInternetSession Session;
	CHttpConnection *pHttpConnection = NULL;
	CFile fTrack;
	CHttpFile* pHTTP = NULL;
	CString strHTTPBoundary;
	CString strPreFileData;
	CString strPostFileData;
	DWORD dwTotalRequestLength = 0;
	DWORD dwChunkLength = 0;
	DWORD dwReadLength = 0;
	DWORD dwResponseLength = 0;
	TCHAR szError[MAX_PATH] = {0};
	void* pBuffer = NULL;
	LPSTR szResponse;
	CString strResponse;
	BOOL bSuccess = TRUE;
	CString strDebugMessage;
	//读取文件
	if (FALSE == fTrack.Open(strPicName, CFile::modeRead | CFile::shareDenyWrite))
	{
		CLIENT_ERROR("Open File Failed path = %s", strPicName);
		return;
	}
	int iRecordID = 1;
	strHTTPBoundary = _T("---------------------------7b4a6d158c9");//定义边界值
	CString pcmname = strPicName;
	pcmname = pcmname.Mid(pcmname.ReverseFind('\\') + 1);//获取抓取的图片名字
	char *putf8Buffer = NULL;
	if(ansi2utf8(pcmname.GetBuffer(), &putf8Buffer) > 0)
	{
		pcmname.ReleaseBuffer();
		pcmname.Format("%s", putf8Buffer);
		delete []putf8Buffer;
		putf8Buffer = NULL;
	}
	else
	{
		pcmname.ReleaseBuffer();
		pcmname = "未知图片名称";
	}

	PREVIEW_INFO("获取的文件名:%s ",pcmname);

	strPreFileData = MakePreFileData(strHTTPBoundary, pcmname, iRecordID);
	strPostFileData = MakePostFileData(strHTTPBoundary);
	dwTotalRequestLength = strPreFileData.GetLength() + strPostFileData.GetLength() + fTrack.GetLength();//计算整个包的总长度


	dwChunkLength = 64 * 1024;
	pBuffer = malloc(dwChunkLength);
	if (NULL == pBuffer)
	{
		PREVIEW_ERROR("Fun_UploadPic 申请内存失败 长度 = %d", dwChunkLength);
		fTrack.Close();
		return;
	}

	try
	{
		pHttpConnection = Session.GetHttpConnection(strIP,(INTERNET_PORT)nPort);
		pHTTP = pHttpConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST, strRemote);
		if(NULL==pHTTP)
			return;
		pHTTP->AddRequestHeaders(MakeRequestHeaders(strHTTPBoundary));//发送包头请求

		pHTTP->SendRequestEx(dwTotalRequestLength, HSR_SYNC | HSR_INITIATE);

#ifdef _UNICODE
		pHTTP->Write(W2A(strPreFileData), strPreFileData.GetLength());
#else
		pHTTP->Write((LPSTR)(LPCSTR)strPreFileData, strPreFileData.GetLength());
#endif

	        dwReadLength = -1;
		while (0 != dwReadLength)
		{
		        strDebugMessage.Format(_T("%u / %u\n"), fTrack.GetPosition(), fTrack.GetLength());

			TRACE(strDebugMessage);
			dwReadLength = fTrack.Read(pBuffer, dwChunkLength);
			if (0 != dwReadLength)
			{
				pHTTP->Write(pBuffer, dwReadLength);//写入服务器本地文件,用二进制进行传送
			}
		}

#ifdef _UNICODE
		pHTTP->Write(W2A(strPostFileData), strPostFileData.GetLength());
#else
		pHTTP->Write((LPSTR)(LPCSTR)strPostFileData, strPostFileData.GetLength());
#endif

	        pHTTP->EndRequest(HSR_SYNC);
		dwResponseLength = pHTTP->GetLength();
		while (0 != dwResponseLength)
		{
		        szResponse = (LPSTR)malloc(dwResponseLength + 1);
			szResponse[dwResponseLength] = '\0';
			pHTTP->Read(szResponse, dwResponseLength);
			strResponse += szResponse;
			free(szResponse);
			dwResponseLength = pHTTP->GetLength();
		}
	}
	catch (CException* e)
	{
		e->GetErrorMessage(szError, MAX_PATH);
		e->Delete();
		AfxMessageBox(szError);
		bSuccess = FALSE;
	}

	pHTTP->Close();
	delete pHTTP;

	fTrack.Close();

	if (NULL != pBuffer)
	{
		free(pBuffer);
	}
}

int ansi2utf8(const char *pSrc, char**pBuffer)
{
	if (pSrc == NULL || strlen(pSrc) == 0)
	{
		return 0;
	}
	int num = MultiByteToWideChar(CP_ACP, NULL, pSrc, -1, NULL, NULL);
	wchar_t *wBuffer = new(std::nothrow) wchar_t[num];
	memset(wBuffer, 0, num * sizeof(wchar_t));
	if (wBuffer == NULL)
	{
		PREVIEW_ERROR("ansi2utf8 malloc wbuff failed!");
		return -1;
	}
	MultiByteToWideChar(CP_ACP, NULL, pSrc, -1, wBuffer, num);
	int len = WideCharToMultiByte(CP_UTF8, 0, wBuffer, num - 1, NULL, NULL, NULL, NULL);
	*pBuffer = new(std::nothrow) char[len + 1];
	memset(*pBuffer, 0, (len + 1));
	if (*pBuffer == NULL)
	{
		PREVIEW_ERROR("ansi2utf8 malloc *pBuffer failed!");
		return -2;
	}
	WideCharToMultiByte(CP_UTF8, 0, wBuffer, num - 1, *pBuffer, len, NULL, NULL);
	delete []wBuffer;
	wBuffer=NULL;
	return (len + 1);
}

CString MakeRequestHeaders(CString& strBoundary)
{
	CString strFormat;
	CString strData;
	strFormat = _T("Content-Type: multipart/form-data; boundary=%s\r\n");
	strData.Format(strFormat, strBoundary);
	return strData;
}

CString MakePreFileData(CString &strBoundary, CString &strFileName, int iRecordID)
{
	/**/
	//Content-Type:
	//JPG image/pjpeg
	//PNG image/x-png
	//BMP image/bmp
	//TIF image/tiff
	//GIF image/gif
	CString strFormat;
	CString strData;

	strFormat += _T("--%s");
	strFormat += _T("\r\n");
	strFormat += _T("Content-Disposition: form-data; name=\"file\"; filename=\"%s\"");

	strFormat += _T("\r\n");
	strFormat += _T("Content-Type: image/pjpeg");

	strFormat += _T("\r\n\r\n");
	strData.Format(strFormat,  strBoundary, strFileName);//

	return strData;
}

CString MakePostFileData(CString &strBoundary)//发送请求包
{
	CString strFormat;
	CString strData;
	strFormat = _T("\r\n");	
	strFormat += _T("--%s");
	strFormat += _T("\r\n");
	strFormat += _T("Content-Disposition: form-data; name=\"upload\"");
	strFormat += _T("\r\n\r\n");
	strFormat += _T("hello");
	strFormat += _T("\r\n");
	strFormat += _T("--%s--");
	strFormat += _T("\r\n");
	strData.Format(strFormat, strBoundary, strBoundary);
	return strData;
}

你可能感兴趣的:(学习笔记,c++开发知识点总结)