HTTP上传文件至服务器

 

本人最近开发MFC项目需要利用HTTP协议,上传文件至服务器,需要以二进制传输,Content-Type类型为: multipart/form-data,注意需要定义相关边界开始和结束

利用WinInt开发包HTTP封装

 //HTTP服务
 CHttpConnection* m_pHC;
 CHttpFile* m_pHF;
 CInternetSession m_cis;

以下为上传文件相关代码:

#include
CString MakeRequestHeaders(CString &strBoundary)//包头
{
 CString strFormat;
 CString strData;
 //二进制文件传送Content-Type类型为: multipart/form-data
 strFormat = _T("Content-Type: multipart/form-data;charset=UTF-8;boundary=%s\r\n");

 strData.Format(strFormat, strBoundary);
 return strData;
}

CString MakePreFileData( CString &strBoundary, CString &strFileName)
{
 
 CString strFormat;
 CString strData;

 if(!strFileName.Compare(TEXT("ecg.txt")))//文件一
 {
  strFormat += _T("\r\n");
  strFormat += _T("--%s");
  strFormat += _T("\r\n");
  strFormat += _T("Content-Disposition: form-data; name=\"ecg_file\"; filename=\"ecg.txt\"");
  strFormat += _T("\r\n");
  strFormat += _T("Content-Type: text/plain");
  strFormat += _T("\r\n\r\n");
  strData.Format(strFormat, strBoundary);
 }
 else if(!strFileName.Compare(TEXT("ppg.txt")))//文件二
 {
  strFormat += _T("\r\n");
  strFormat += _T("--%s");
  strFormat += _T("\r\n");
  strFormat += _T("Content-Disposition: form-data; name=\"ppg_file\"; filename=\"ppg.txt\"");
  strFormat += _T("\r\n");
  strFormat += _T("Content-Type: text/plain");
  strFormat += _T("\r\n\r\n");
  strData.Format(strFormat, strBoundary);
 }
 return strData;
}

CString MakePostFileData(CString &strBoundary)
{
 CString strFormat;
 CString strData;

 strFormat += _T("\r\n");
 strFormat += _T("--%s--");
 strFormat += _T("\r\n");

 strData.Format(strFormat, strBoundary);

 return strData;
}


BOOL PostEcgPpg(CString& strURL,const CString& strLocalPath)//发送数据,strLocalPath为本地路径
{

 CString pcmnameecg = TEXT("ecg.txt");
 CString pcmnameppg = TEXT("ppg.txt");
 CString _mEcgFilePath = strLocalPath + pcmnameecg;
 CString _mPpgFilePath = strLocalPath + pcmnameppg;

 CFile fTrackEcg;
 CFile fTrackPpg;
 CString strHTTPBoundary;
 CString strPreFileDataEcg;
 CString strPreFileDataPpg;
 CString strPostFileData;
 DWORD dwTotalRequestLength;
 DWORD dwChunkLength;
 DWORD dwReadLength;
 DWORD dwResponseLength;
 TCHAR szError[MAX_PATH];
 void* pBuffer;
 LPSTR szResponse;
 CString strResponse;
 BOOL bSuccess = TRUE;
 CString strDebugMessage;
 //打开上传文件
 if (FALSE == fTrackEcg.Open(_mEcgFilePath, CFile::modeRead | CFile::shareDenyWrite))
 {
  AfxMessageBox(_T("Unable to open the file."));
  return FALSE;
 }
 if (FALSE == fTrackPpg.Open(_mPpgFilePath, CFile::modeRead | CFile::shareDenyWrite))
 {
  AfxMessageBox(_T("Unable to open the file."));
  return FALSE;
 }
 //定义边界值
 strHTTPBoundary = _T("---------------------------7b4a6d158c9boundary");
 strPreFileDataEcg = MakePreFileData(strHTTPBoundary,pcmnameecg);
 strPreFileDataPpg = MakePreFileData(strHTTPBoundary,pcmnameppg);
 strPostFileData = MakePostFileData(strHTTPBoundary);
 //包总长度
 dwTotalRequestLength = strPreFileDataEcg.GetLength() + strPreFileDataPpg.GetLength()
  + strPostFileData.GetLength() + fTrackEcg.GetLength() + fTrackPpg.GetLength();//计算整个包的总长度

 dwChunkLength = 64 * 1024;
 pBuffer = malloc(dwChunkLength);

 if (NULL == pBuffer)
 {
  return FALSE;
 }
 try
 {
  m_pHC = m_cis.GetHttpConnection(m_ServerName,m_nPort);// IP地址和端口
  m_pHF = m_pHC->OpenRequest(CHttpConnection::HTTP_VERB_POST, strURL);
  //发送包头请求
  m_pHF->AddRequestHeaders(MakeRequestHeaders(strHTTPBoundary));
  m_pHF->AddRequestHeaders(TEXT("Accept-Encoding: gzip"));
  m_pHF->AddRequestHeaders(TEXT("Connection: close"));

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

  USES_CONVERSION;
  //写入服务器所需信息
#ifdef _UNICODE
  m_pHF->Write(W2A(strPreFileDataEcg), strPreFileDataEcg.GetLength());
#else
  m_pHF->Write((LPSTR)(LPCSTR)strPreFileDataEcg, strPreFileDataEcg.GetLength());
#endif
  dwReadLength = -1;
  while (0 != dwReadLength)
  {
   strDebugMessage.Format(_T("%u / %u\n"), fTrackEcg.GetPosition(), fTrackEcg.GetLength());
   TRACE(strDebugMessage);
   //读取文件内容
   dwReadLength = fTrackEcg.Read(pBuffer, dwChunkLength);
   if (0 != dwReadLength)
   {
    //写入服务器本地文件,用二进制进行传送
    m_pHF->Write(pBuffer, dwReadLength);
   }
  }
  //写入服务器所需信息
#ifdef _UNICODE
  m_pHF->Write(W2A(strPreFileDataPpg), strPreFileDataPpg.GetLength());
#else
  m_pHF->Write((LPSTR)(LPCSTR)strPreFileDataPpg, strPreFileDataPpg.GetLength());
#endif 
  dwReadLength = -1;
  while (0 != dwReadLength)
  {
   strDebugMessage.Format(_T("%u / %u\n"), fTrackPpg.GetPosition(), fTrackPpg.GetLength());
   TRACE(strDebugMessage);
   //读取文件内容
   dwReadLength = fTrackPpg.Read(pBuffer, dwChunkLength);
   if (0 != dwReadLength)
   {
    //写入服务器本地文件,用二进制进行传送
    m_pHF->Write(pBuffer, dwReadLength);
   }
  }

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

  m_pHF->EndRequest(HSR_SYNC);

  RecvProc(strResponse);
  AfxMessageBox(strResponse);
 }
 catch (CException* e)
 {
  e->GetErrorMessage(szError, MAX_PATH);
  e->Delete();
  AfxMessageBox(szError);
  bSuccess = FALSE;
 }

 m_pHF->Close();
 delete m_pHF;

 fTrackPpg.Close();
 fTrackEcg.Close();

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

以下为上传文件相关抓包信息:

 请求头信息:

(Request-Line):POST /MiddleWare//measure/uploadEcgPpg?params=%7B%22memberId%22:26029%2C%22param%22:%7B%22deviceCode%22:%22%22%2C%22ppgFs%22:60%2C%22measureTime%22:%2220150901171440%22%2C%22ecgFs%22:250%2C%22spo%22:97%2C%22bluetoothMacAddr%22:%22%22%2C%22timeLength%22:0%7D%2C%22loginLog%22:%222015%2D09%2D01+17:14:40%22%2C%22session%22:%22f91dc047%2D90fb%2D4347%2D9991%2D3de54d29e111%22%2C%22version%22:%22v1%2E0%22%7D HTTP/1.1
Content-Type:multipart/form-data;charset=UTF-8;boundary=---------------------------7b4a6d158c9boundary
Accept-Encoding:gzip
Connection:Close
User-Agent:HRPFBO
Host:192.168.11.22:8888
Content-Length:28478
Cache-Control:no-cache

响应头信息:

(Status-Line):HTTP/1.1 200 OK
Server:Apache-Coyote/1.1
Content-Type:text/html;charset=UTF-8
Content-Length:74
Date:Tue, 01 Sep 2015 09:15:10 GMT
Connection:close

请求发送流:

POST /MiddleWare//measure/uploadEcgPpg?params=%7B%22memberId%22:26029%2C%22param%22:%7B%22deviceCode%22:%22%22%2C%22ppgFs%22:60%2C%22measureTime%22:%2220150901171440%22%2C%22ecgFs%22:250%2C%22spo%22:97%2C%22bluetoothMacAddr%22:%22%22%2C%22timeLength%22:0%7D%2C%22loginLog%22:%222015%2D09%2D01+17:14:40%22%2C%22session%22:%22f91dc047%2D90fb%2D4347%2D9991%2D3de54d29e111%22%2C%22version%22:%22v1%2E0%22%7D HTTP/1.1
Content-Type: multipart/form-data;charset=UTF-8;boundary=---------------------------7b4a6d158c9boundary
Accept-Encoding: gzip
Connection: Close
User-Agent: HRPFBO
Host: 192.168.11.22:8888
Content-Length: 28478
Cache-Control: no-cache

 

-----------------------------7b4a6d158c9boundary
Content-Disposition: form-data; name="ecg_file"; filename="ecg.txt"
Content-Type: text/plain

ffffff41ffffff41ffffff41ffffff41ffffff40ffffff40ffffff3fffffff41ffffff41ffffff40ffffff41ffffff3bffffff40ffffff41ffffff41ffffff41ffffff41ffffff41ffffff41ffffff40ffffff41ffffff41ffffff41ffffff41ffffff41ffffff41ffffff41ffffff41ffffff40ffffff41ffffff4
-----------------------------7b4a6d158c9boundary
Content-Disposition: form-data; name="ppg_file"; filename="ppg.txt"
Content-Type: text/plain

7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f3
-----------------------------7b4a6d158c9boundary--

 

响应发送流:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=UTF-8
Content-Length: 74
Date: Tue, 01 Sep 2015 09:15:10 GMT
Connection: close

{"message":"成功","state":0,"content":"{\"ecg_id\":394,\"ppg_id\":319}"}

 

 

你可能感兴趣的:(HTTP协议应用)