zoukankan      html  css  js  c++  java
  • VC编写自己构造http协议数据的post上传图片类(MFC环境 带编码转换)(转)

    上次用VC写了个MFC环境下的post数据类,地址:

    /Html/diannaojishu/2009-10/4905858580.html

    这次将这个类进行扩展,可以post图片。但这两个post所使用的方法不一样。

    post数据,是直接在http协议头将Content-Type设为application/x-www-form-urlencoded,这样 服务器会将提交的数据,当作表单数据处理。发送的数据格式也为:userid=lilu&data=post图片类&name=天漏客。 而post图片则是自己构造http协议数据,将http协议头的Content-Type设为multipart/form-data,同时还要加上 boundary=xxxxxxx(xxxxxxx表示一个字符串),后面的协议数据内容将要以这个xxxxxxx来进行分隔。发送的数据格式为:

    ---------------2389jhrwfjsjd9823
    Content-Disposition: form-data; name="userid"

    27EF272F28239E5A34EE223FADFWAFAEaE

    类源码下载:点击浏览下一页[点击浏览该文件:SendData类源码.rar]

    实例源码下载:点击浏览下一页[点击浏览该文件:UploadPhoto实例加源码.rar]

    首先说一下本类的方便之处。

    1、使用方便,步骤简单。
    2、发送图片时,还可以构造其他数据。
    3、兼容_MBCS和_UNICODE模式,并且能使用GB2312和UTF8两种编码进行发送与接收,类自动实现转换。

    首先说一下这个类的使用,方法比较简单。

    1、在工程中加入SendData.h和SendData.cpp文件,然后包含头文件,就可以定义类。

    CSendData    MySend;

    2、设置服务器参数。

     MySend.SetServerParam(_T(www.lilu.name),_T("/posttest.asp"),80);

    3、如果同时要包含数据,就要先构造数据。

     MySend.MakePostData(_T("userid"),_T("lilu"));
     MySend.MakePostData(_T("name"),_T("天漏客"));
     MySend.MakePostData(_T("homepage"),_T(www.lilu.name));

    4、发送图片。定义好接收数据的指针,以及发送和接收的编码。

     TCHAR  *pRecvData = NULL; //接收数据的指针
     DWORD  dwRecvSize = 0;  //接收数据的大小
     DWORD  dwRetSend = 0;  //发送函数返回值
     int   SendCode = HTTP_POST_GB2312,RecvCode =HTTP_POST_GB2312; //发送与接收的编码
     
    dwRetSend = MySend.PostPicDataMethod(_T("c:\\pic\\测试图片.jpg"),_T("filename"),
      &pRecvData,dwRecvSize,
      SendCode,RecvCode);
     //处理接收数据,返回值。
     //99:图片不存在
     //100:正常成功
     //101:服务器无法连接
     //102:提交页面无法打开
     //103:数据发送失败
     //104:服务器处理失败
     //500:异常错误

    5、处理结果

    类自动的根据编译环境,将返回指针转换为LPTSTR类型,所以你只需要定义一个LPTSTR类型的指针,将其地址传递给发送函数即可。类会自己分 配内存存储返回的结果,并且会自动释放。所以使用时要注意,当这个类的作用域结束时,相应的接收数据内存也会释放掉,你可以将接收数据另拷贝一份,或者在 它的作用域内处理掉也可。

    CString strRecv(pRecvData);    //将接收数据复制到strRecv中。

    6、完毕。

    测试一下啊!界面如下:

    1. 我本地IIS假设服务器,写入上传代码。然后使用软件提交,抓包如下:  
    2.   
    3. POST /upload.asp HTTP/1.1  
    4. Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/xaml+xml,*/* 
    5. Accept-Encoding: gzip, deflate 
    6. Accept-Language: zh-cn 
    7. Content-Type: multipart/form-data; boundary=-------------2389jhrwfjsjd9823 
    8. Cache-Control: no-cache 
    9. User-Agent: UploadPhoto 
    10. Host: 192.168.2.111 
    11. Content-Length: 39725 
    12.  
    13. ---------------2389jhrwfjsjd9823 
    14. Content-Disposition: form-data; name="Crypt" 
    15.  
    16. 10 
    17. ---------------2389jhrwfjsjd9823 
    18. Content-Disposition: form-data; name="type" 
    19.  
    20. 200 
    21. ---------------2389jhrwfjsjd9823 
    22. Content-Disposition: form-data; name="userid" 
    23.  
    24. 27EF272F28239E5A34EE223FADFWAFAEaE 
    25. ---------------2389jhrwfjsjd9823 
    26. Content-Disposition: form-data; name="filename"; filename="D:\Lilu.Other\QQ图片\软件工程图解.jpg" 
    27. Content-Type: image/pjpeg 
    28.  
    29. ……………………省略图片二进制数据……………… 
    30.  
    31. ---------------2389jhrwfjsjd9823 
    32. Content-Disposition: form-data; name="Submit" 
    33.  
    34. submit 
    35. ---------------2389jhrwfjsjd9823-- 
    36.  
    37. 这就是整个软件发送的数据,懂http协议的话,很容易理解这些数据。服务器返回: 
    38.  
    39. HTTP/1.1 200 OK 
    40. Server: Microsoft-IIS/5.1 
    41. Date: Wed, 04 Nov 2009 02:48:12 GMT 
    42. Content-Length: 171 
    43. Content-Type: text/html 
    44. Set-Cookie: ASPSESSIONIDSCRSBCRQ=ACBHPAHADINHKHIANAALFKOO; path=/ 
    45. Cache-control: private 
    46.  
    47.   
    48. <html>  
    49. <head>  
    50. <title>文件上传</title>  
    51. </head>  
    52. <body>  
    53. <font size=2>文件上传成功 [ <a href=# onclick=history.go(-1)>继续上传</a> ]</font>  
    54. </body>  
    55. </html>  
    56.  
    57.  最后贴一下这个类的源代码: 
    58.  
    59. ======================================================= 
    60. 首先是头文件:SendData.h 
    61.  
    62. // SendData.h: interface for the CSendData class. 
    63. // 
    64. ////////////////////////////////////////////////////////////////////// 
    65.  
    66. #if !defined(AFX_SENDDATA_H__F98D6FB7_D797_4947_A17E_13E88D20F35F__INCLUDED_) 
    67. #define AFX_SENDDATA_H__F98D6FB7_D797_4947_A17E_13E88D20F35F__INCLUDED_ 
    68.  
    69. #if _MSC_VER > 1000 
    70. #pragma once 
    71. #endif // _MSC_VER > 1000 
    72.  
    73. #include <afxinet.h> 
    74. #include <string> 
    75. using std::string; 
    76.  
    77. #define HTTP_POST_GB2312 1 //发送和接收的网页编码 
    78. #define HTTP_POST_UTF8  2 
    79.  
    80. class CSendData   
    81. { 
    82. public: 
    83.  CSendData(); 
    84.  virtual ~CSendData(); 
    85.  void SetServerParam(TCHAR ServerName[100],TCHAR ObjectName[100],WORD Port); 
    86.  //构造协议数据内容 
    87.  BOOL MakePostData(LPCTSTR pPostName, LPCTSTR pPostValue); 
    88.  BOOL MakePostData(LPCTSTR pPostName,int iPostValue); 
    89.  //发送带图片的数据 
    90.  DWORD PostPicDataMethod(TCHAR PicPath[MAX_PATH],LPCTSTR pPostName, 
    91.   LPTSTR *pRecvData, DWORD &RecvSize, 
    92.   int SendCode = HTTP_POST_GB2312,//发送和接收的编码 
    93.   int RecvCode = HTTP_POST_GB2312);  
    94.  //发送文本类数据 
    95.  DWORD PostDataMethod(LPCTSTR strDataSend, int DataSize,  
    96.   LPTSTR *pRecvData, DWORD &RecvSize, 
    97.   int SendCode = 1,int RecvCode = 1); 
    98. private: 
    99.  CString   m_strBoundary; //数据分隔符 
    100.  CString   m_strHeaderData; //协议头数据 
    101.  CString   m_strPostData; //协议正文数据 
    102.  CString   m_strEndData; //协议尾数据 
    103.  
    104.  void MakeHeaderData(); //构造协议头部数据 
    105.  void MakeEndData();  //构造协议尾部数据 
    106.  void MakePostPicData(LPCTSTR pPostName, LPCTSTR pPostValue); //构造图片前缀数据 
    107.  
    108.  //返回值为图片大小,返回值为0表示不存在。 
    109.  DWORD GetExistPic(TCHAR PicPath[MAX_PATH]); 
    110.  //服务器参数 
    111.  INTERNET_PORT m_nPort;  
    112.  TCHAR m_tzObjectName[100]; 
    113.  TCHAR m_tzServerName[100]; 
    114.  /////编码转换///////////////////////////////////////////////////////////// 
    115.  char * m_lpUTF8;   //UTF8编码缓存指针 
    116.  char * m_lpMultiByte; //Multil多字节编码指针 
    117.  wchar_t * m_wpWideChar;  //Widechar编码缓存指针 
    118.  int  m_nUTF8Len;  
    119.  int  m_nMultiByteLen; 
    120.  int  m_nWideCharLen; 
    121.   
    122.  void WideCharToUTF8(LPCWSTR wpWideData, int WideLen); 
    123.  void MultiByteToUTF8(LPCSTR lpMultiData, int MultiLen); 
    124.  void UTF8ToWideChar(LPCSTR pUTF8,int UTF8Len); 
    125.  void UTF8ToMultiByte(LPCSTR pUTF8, int UTF8Len); 
    126.  void MultiToWide(LPCSTR strDataSend, int DataSize); 
    127.  void MultiToMulti(LPCSTR strDataSend, int DataSize); 
    128.  void WideToMulti(LPCWSTR wpWideData, int WideLen); 
    129.  
    130. }; 
    131.  
    132. #endif // !defined(AFX_SENDDATA_H__F98D6FB7_D797_4947_A17E_13E88D20F35F__INCLUDED_) 
    133.  
    134.  
    135. ======================================================== 
    136. 接着是SendData.cpp文件。 
    137.  
    138. // UploadPhotoDlg.cpp : implementation file 
    139. // 
    140.  
    141. #include "stdafx.h" 
    142. #include "UploadPhoto.h" 
    143. #include "UploadPhotoDlg.h" 
    144.  
    145. #include "SendData.h" 
    146.  
    147. #ifdef _DEBUG 
    148. #define new DEBUG_NEW 
    149. #undef THIS_FILE 
    150. static char THIS_FILE[] = __FILE__; 
    151. #endif 
    152.  
    153. ///////////////////////////////////////////////////////////////////////////// 
    154. // CUploadPhotoDlg dialog 
    155.  
    156. CUploadPhotoDlg::CUploadPhotoDlg(CWnd* pParent /*=NULL*/)  
    157.  : CDialog(CUploadPhotoDlg::IDD, pParent)  
    158. {  
    159.  //{{AFX_DATA_INIT(CUploadPhotoDlg)   
    160.  m_strPhotoPath = _T("");  
    161.  m_nPort = 80;  
    162.  m_strRecvData = _T("");  
    163. //  m_strObjectName = _T("/frontend_dev.php/device/retriever");   
    164. //  m_strServerName = _T("trunk.xunhui1.net");   
    165.  m_strObjectName = _T("/upload.asp");  
    166.  m_strServerName = _T("192.168.2.111");  
    167.  m_PostName = _T("userid");  
    168.  m_PostValue = _T("27EF272F28239E5A34EE223FADFWAFAEaE");  
    169.  //}}AFX_DATA_INIT   
    170.  // Note that LoadIcon does not require a subsequent DestroyIcon in Win32   
    171.  m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);  
    172. }  
    173.   
    174. void CUploadPhotoDlg::DoDataExchange(CDataExchange* pDX)  
    175. {  
    176.  CDialog::DoDataExchange(pDX);  
    177.  //{{AFX_DATA_MAP(CUploadPhotoDlg)   
    178.  DDX_Text(pDX, IDC_EDIT_OBJECTNAME, m_strObjectName);  
    179.  DDX_Text(pDX, IDC_EDIT_PHOTOPATH, m_strPhotoPath);  
    180.  DDX_Text(pDX, IDC_EDIT_PORT, m_nPort);  
    181.  DDX_Text(pDX, IDC_EDIT_RECVDATA, m_strRecvData);  
    182.  DDX_Text(pDX, IDC_EDIT_SERVERNAME, m_strServerName);  
    183.  DDX_Text(pDX, IDC_EDIT_POSTDATANAME, m_PostName);  
    184.  DDX_Text(pDX, IDC_EDIT_POSTDATAVALUE, m_PostValue);  
    185.  //}}AFX_DATA_MAP   
    186. }  
    187.   
    188. BEGIN_MESSAGE_MAP(CUploadPhotoDlg, CDialog)  
    189.  //{{AFX_MSG_MAP(CUploadPhotoDlg)   
    190.  ON_WM_PAINT()  
    191.  ON_WM_QUERYDRAGICON()  
    192.  ON_BN_CLICKED(IDC_BTN_SEND, OnBtnSend)  
    193.  ON_BN_CLICKED(IDC_BTN_FILEOPEN, OnBtnFileopen)  
    194.  //}}AFX_MSG_MAP   
    195. END_MESSAGE_MAP()  
    196.   
    197. /////////////////////////////////////////////////////////////////////////////   
    198. // CUploadPhotoDlg message handlers   
    199.   
    200. BOOL CUploadPhotoDlg::OnInitDialog()  
    201. {  
    202.  CDialog::OnInitDialog();  
    203.   
    204.  // Set the icon for this dialog.  The framework does this automatically   
    205.  //  when the application's main window is not a dialog   
    206.  SetIcon(m_hIcon, TRUE);   // Set big icon   
    207.  SetIcon(m_hIcon, FALSE);  // Set small icon   
    208.    
    209.  // TODO: Add extra initialization here   
    210.  ((CButton*)GetDlgItem(IDC_RADIO_SENDGB2312))->SetCheck(TRUE);  
    211.  ((CButton*)GetDlgItem(IDC_RADIO_RECVGB2312))->SetCheck(TRUE);  
    212.   
    213.  return TRUE;  // return TRUE  unless you set the focus to a control   
    214. }  
    215.   
    216. // If you add a minimize button to your dialog, you will need the code below   
    217. //  to draw the icon.  For MFC applications using the document/view model,   
    218. //  this is automatically done for you by the framework.   
    219.   
    220. void CUploadPhotoDlg::OnPaint()   
    221. {  
    222.  if (IsIconic())  
    223.  {  
    224.   CPaintDC dc(this); // device context for painting   
    225.   
    226.   SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);  
    227.   
    228.   // Center icon in client rectangle   
    229.   int cxIcon = GetSystemMetrics(SM_CXICON);  
    230.   int cyIcon = GetSystemMetrics(SM_CYICON);  
    231.   CRect rect;  
    232.   GetClientRect(&rect);  
    233.   int x = (rect.Width() - cxIcon + 1) / 2;  
    234.   int y = (rect.Height() - cyIcon + 1) / 2;  
    235.   
    236.   // Draw the icon   
    237.   dc.DrawIcon(x, y, m_hIcon);  
    238.  }  
    239.  else  
    240.  {  
    241.   CDialog::OnPaint();  
    242.  }  
    243. }  
    244.   
    245. // The system calls this to obtain the cursor to display while the user drags   
    246. //  the minimized window.   
    247. HCURSOR CUploadPhotoDlg::OnQueryDragIcon()  
    248. {  
    249.  return (HCURSOR) m_hIcon;  
    250. }  
    251.   
    252. void CUploadPhotoDlg::OnBtnSend()   
    253. {  
    254.  // TODO: Add your control notification handler code here   
    255.  GetDlgItem(IDC_BTN_SEND)->EnableWindow(FALSE);  
    256.    
    257.  UpdateData(TRUE);  
    258.  //定义发送类   
    259.  CSendData MySend;   
    260.  TCHAR  *pRecvData = NULL; //接收数据的指针   
    261.  DWORD  dwRecvSize = 0;  //接收数据的大小   
    262.  DWORD  dwRetSend = 0;  //发送函数返回值   
    263.  int   SendCode = HTTP_POST_GB2312,RecvCode =HTTP_POST_GB2312; //发送与接收的编码   
    264.  //设置服务器参数   
    265.  MySend.SetServerParam((LPTSTR)(LPCTSTR)m_strServerName,(LPTSTR)(LPCTSTR)m_strObjectName,m_nPort);  
    266.   
    267.  //确定发送方法   
    268.  if (1 == ((CButton*)GetDlgItem(IDC_RADIO_SENDGB2312))->GetCheck())  
    269.  {  
    270.   SendCode = HTTP_POST_GB2312;  
    271.  }  
    272.  else  
    273.  {  
    274.   SendCode = HTTP_POST_UTF8;  
    275.  }  
    276.  //确定接收编码   
    277.  if (1 == ((CButton*)GetDlgItem(IDC_RADIO_RECVGB2312))->GetCheck())  
    278.  {  
    279.   RecvCode = HTTP_POST_GB2312;   
    280.  }  
    281.  else  
    282.  {  
    283.   RecvCode = HTTP_POST_UTF8;  
    284.  }  
    285.  //必须先构造数据包   
    286.  MySend.MakePostData(_T("Crypt"),_T("10"));  
    287.  MySend.MakePostData(_T("type"),_T("200"));  
    288.  MySend.MakePostData(m_PostName,m_PostValue);  
    289.  //发送   
    290.  dwRetSend = MySend.PostPicDataMethod((LPTSTR)(LPCTSTR)m_strPhotoPath,_T("filename"),  
    291.   &pRecvData,dwRecvSize,  
    292.   SendCode,RecvCode);  
    293.  //处理接收数据   
    294.  //99:图片不存在   
    295.  //100:正常成功   
    296.  //101:服务器无法连接   
    297.  //102:提交页面无法打开   
    298.  //103:数据发送失败   
    299.  //104:服务器处理失败   
    300.  //500:异常错误   
    301.  if (dwRetSend == 100)  
    302.  {  
    303.   MessageBox(_T("发送成功"));  
    304.  }  
    305.  else if (dwRetSend == 99 )  
    306.  {  
    307.   MessageBox(_T("发送成功"));  
    308.  }  
    309.  else if (dwRetSend == 101 )  
    310.  {  
    311.   MessageBox(_T("服务器无法连接"));  
    312.  }  
    313.  else if (dwRetSend == 102 )  
    314.  {  
    315.   MessageBox(_T("提交页面无法打开"));  
    316.  }  
    317.  else if (dwRetSend == 103 )  
    318.  {  
    319.   MessageBox(_T("数据发送失败"));  
    320.  }  
    321.  else if (dwRetSend == 104 )  
    322.  {  
    323.   MessageBox(_T("服务器处理失败"));  
    324.  }  
    325.  else if (dwRetSend == 500 )  
    326.  {  
    327.   MessageBox(_T("异常错误"));  
    328.  }  
    329.  //更新返回数据框   
    330.  m_strRecvData = pRecvData;  
    331.  UpdateData(FALSE);  
    332.     
    333.  GetDlgItem(IDC_BTN_SEND)->EnableWindow(TRUE);  
    334.   
    335. }  
    336.   
    337. void CUploadPhotoDlg::OnBtnFileopen()   
    338. {  
    339.  // TODO: Add your control notification handler code here   
    340.  TCHAR tzFilter[] = _T("jpg图片(*.jpg;*.jpeg)|*.jpg;*.jpeg|gif图片(*.gif)|*.gif|所有文件(*.*)|*.*||");  
    341.  CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_ENABLESIZING|OFN_EXPLORER,  
    342.   tzFilter,NULL);  
    343.  if (dlg.DoModal() == IDOK)  
    344.  {  
    345.   m_strPhotoPath = dlg.GetPathName();  
    346.   UpdateData(FALSE);  
    347.  }  
    348.   
  • 相关阅读:
    搬运好文章->>>>>子网划分详解
    搬运好文章->>>>>子网掩码详解
    搬运好文章->>>>>IP地址和MAC地址详解
    搬运好文章->>>>>计算机中进制之间的关系和转换
    extend 与 append 的区别
    数据类型---字符串
    多引号的作用,字符串格式化
    列表复制的几种方法
    十六进制和二进制转换
    python奇偶数求和
  • 原文地址:https://www.cnblogs.com/zhwl/p/2772905.html
Copyright © 2011-2022 走看看