上次用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;//接收数据的指针
DWORDdwRecvSize = 0;//接收数据的大小
DWORDdwRetSend = 0;//发送函数返回值
intSendCode = 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、完毕。
测试一下啊!界面如下:
我本地IIS假设服务器,写入上传代码。然后使用软件提交,抓包如下:
POST /upload.asp HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/xaml+xml,*/*
Accept-Encoding: gzip, deflate
Accept-Language: zh-cn
Content-Type: multipart/form-data; boundary=-------------2389jhrwfjsjd9823
Cache-Control: no-cache
User-Agent: UploadPhoto
Host: 192.168.2.111
Content-Length: 39725
---------------2389jhrwfjsjd9823
Content-Disposition: form-data; name="Crypt"
10
---------------2389jhrwfjsjd9823
Content-Disposition: form-data; name="type"
200
---------------2389jhrwfjsjd9823
Content-Disposition: form-data; name="userid"
27EF272F28239E5A34EE223FADFWAFAEaE
---------------2389jhrwfjsjd9823
Content-Disposition: form-data; name="filename"; filename="D:\Lilu.Other\QQ图片\软件工程图解.jpg"
Content-Type: image/pjpeg
……………………省略图片二进制数据………………
---------------2389jhrwfjsjd9823
Content-Disposition: form-data; name="Submit"
submit
---------------2389jhrwfjsjd9823--
这就是整个软件发送的数据,懂http协议的话,很容易理解这些数据。服务器返回:
HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1
Date: Wed, 04 Nov 2009 02:48:12 GMT
Content-Length: 171
Content-Type: text/html
Set-Cookie: ASPSESSIONIDSCRSBCRQ=ACBHPAHADINHKHIANAALFKOO; path=/
Cache-control: private
<html>
<head>
<title>文件上传</title>
</head>
<body>
<font size=2>文件上传成功 [ <a href=# onclick=history.go(-1)>继续上传</a> ]</font>
</body>
</html>
最后贴一下这个类的源代码:
=======================================================
首先是头文件:SendData.h
// SendData.h: interface for the CSendData class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_SENDDATA_H__F98D6FB7_D797_4947_A17E_13E88D20F35F__INCLUDED_)
#define AFX_SENDDATA_H__F98D6FB7_D797_4947_A17E_13E88D20F35F__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <afxinet.h>
#include <string>
using std::string;
#define HTTP_POST_GB2312 1 //发送和接收的网页编码
#define HTTP_POST_UTF8 2
class CSendData
{
public:
CSendData();
virtual ~CSendData();
void SetServerParam(TCHAR ServerName[100],TCHAR ObjectName[100],WORD Port);
//构造协议数据内容
BOOL MakePostData(LPCTSTR pPostName, LPCTSTR pPostValue);
BOOL MakePostData(LPCTSTR pPostName,int iPostValue);
//发送带图片的数据
DWORD PostPicDataMethod(TCHAR PicPath[MAX_PATH],LPCTSTR pPostName,
LPTSTR *pRecvData, DWORD &RecvSize,
int SendCode = HTTP_POST_GB2312,//发送和接收的编码
int RecvCode = HTTP_POST_GB2312);
//发送文本类数据
DWORD PostDataMethod(LPCTSTR strDataSend, int DataSize,
LPTSTR *pRecvData, DWORD &RecvSize,
int SendCode = 1,int RecvCode = 1);
private:
CString m_strBoundary; //数据分隔符
CString m_strHeaderData; //协议头数据
CString m_strPostData; //协议正文数据
CString m_strEndData; //协议尾数据
void MakeHeaderData(); //构造协议头部数据
void MakeEndData(); //构造协议尾部数据
void MakePostPicData(LPCTSTR pPostName, LPCTSTR pPostValue); //构造图片前缀数据
//返回值为图片大小,返回值为0表示不存在。
DWORD GetExistPic(TCHAR PicPath[MAX_PATH]);
//服务器参数
INTERNET_PORT m_nPort;
TCHAR m_tzObjectName[100];
TCHAR m_tzServerName[100];
/////编码转换/////////////////////////////////////////////////////////////
char * m_lpUTF8; //UTF8编码缓存指针
char * m_lpMultiByte; //Multil多字节编码指针
wchar_t * m_wpWideChar; //Widechar编码缓存指针
int m_nUTF8Len;
int m_nMultiByteLen;
int m_nWideCharLen;
void WideCharToUTF8(LPCWSTR wpWideData, int WideLen);
void MultiByteToUTF8(LPCSTR lpMultiData, int MultiLen);
void UTF8ToWideChar(LPCSTR pUTF8,int UTF8Len);
void UTF8ToMultiByte(LPCSTR pUTF8, int UTF8Len);
void MultiToWide(LPCSTR strDataSend, int DataSize);
void MultiToMulti(LPCSTR strDataSend, int DataSize);
void WideToMulti(LPCWSTR wpWideData, int WideLen);
};
#endif // !defined(AFX_SENDDATA_H__F98D6FB7_D797_4947_A17E_13E88D20F35F__INCLUDED_)
========================================================
接着是SendData.cpp文件。
// UploadPhotoDlg.cpp : implementation file
//
#include "stdafx.h"
#include "UploadPhoto.h"
#include "UploadPhotoDlg.h"
#include "SendData.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CUploadPhotoDlg dialog
CUploadPhotoDlg::CUploadPhotoDlg(CWnd* pParent /*=NULL*/)
: CDialog(CUploadPhotoDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CUploadPhotoDlg)
m_strPhotoPath = _T("");
m_nPort = 80;
m_strRecvData = _T("");
// m_strObjectName = _T("/frontend_dev.php/device/retriever");
// m_strServerName = _T("trunk.xunhui1.net");
m_strObjectName = _T("/upload.asp");
m_strServerName = _T("192.168.2.111");
m_PostName = _T("userid");
m_PostValue = _T("27EF272F28239E5A34EE223FADFWAFAEaE");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CUploadPhotoDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CUploadPhotoDlg)
DDX_Text(pDX, IDC_EDIT_OBJECTNAME, m_strObjectName);
DDX_Text(pDX, IDC_EDIT_PHOTOPATH, m_strPhotoPath);
DDX_Text(pDX, IDC_EDIT_PORT, m_nPort);
DDX_Text(pDX, IDC_EDIT_RECVDATA, m_strRecvData);
DDX_Text(pDX, IDC_EDIT_SERVERNAME, m_strServerName);
DDX_Text(pDX, IDC_EDIT_POSTDATANAME, m_PostName);
DDX_Text(pDX, IDC_EDIT_POSTDATAVALUE, m_PostValue);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CUploadPhotoDlg, CDialog)
//{{AFX_MSG_MAP(CUploadPhotoDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BTN_SEND, OnBtnSend)
ON_BN_CLICKED(IDC_BTN_FILEOPEN, OnBtnFileopen)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CUploadPhotoDlg message handlers
BOOL CUploadPhotoDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
((CButton*)GetDlgItem(IDC_RADIO_SENDGB2312))->SetCheck(TRUE);
((CButton*)GetDlgItem(IDC_RADIO_RECVGB2312))->SetCheck(TRUE);
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CUploadPhotoDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CUploadPhotoDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CUploadPhotoDlg::OnBtnSend()
{
// TODO: Add your control notification handler code here
GetDlgItem(IDC_BTN_SEND)->EnableWindow(FALSE);
UpdateData(TRUE);
//定义发送类
CSendData MySend;
TCHAR *pRecvData = NULL; //接收数据的指针
DWORD dwRecvSize = 0; //接收数据的大小
DWORD dwRetSend = 0; //发送函数返回值
int SendCode = HTTP_POST_GB2312,RecvCode =HTTP_POST_GB2312; //发送与接收的编码
//设置服务器参数
MySend.SetServerParam((LPTSTR)(LPCTSTR)m_strServerName,(LPTSTR)(LPCTSTR)m_strObjectName,m_nPort);
//确定发送方法
if (1 == ((CButton*)GetDlgItem(IDC_RADIO_SENDGB2312))->GetCheck())
{
SendCode = HTTP_POST_GB2312;
}
else
{
SendCode = HTTP_POST_UTF8;
}
//确定接收编码
if (1 == ((CButton*)GetDlgItem(IDC_RADIO_RECVGB2312))->GetCheck())
{
RecvCode = HTTP_POST_GB2312;
}
else
{
RecvCode = HTTP_POST_UTF8;
}
//必须先构造数据包
MySend.MakePostData(_T("Crypt"),_T("10"));
MySend.MakePostData(_T("type"),_T("200"));
MySend.MakePostData(m_PostName,m_PostValue);
//发送
dwRetSend = MySend.PostPicDataMethod((LPTSTR)(LPCTSTR)m_strPhotoPath,_T("filename"),
&pRecvData,dwRecvSize,
SendCode,RecvCode);
//处理接收数据
//99:图片不存在
//100:正常成功
//101:服务器无法连接
//102:提交页面无法打开
//103:数据发送失败
//104:服务器处理失败
//500:异常错误
if (dwRetSend == 100)
{
MessageBox(_T("发送成功"));
}
else if (dwRetSend == 99 )
{
MessageBox(_T("发送成功"));
}
else if (dwRetSend == 101 )
{
MessageBox(_T("服务器无法连接"));
}
else if (dwRetSend == 102 )
{
MessageBox(_T("提交页面无法打开"));
}
else if (dwRetSend == 103 )
{
MessageBox(_T("数据发送失败"));
}
else if (dwRetSend == 104 )
{
MessageBox(_T("服务器处理失败"));
}
else if (dwRetSend == 500 )
{
MessageBox(_T("异常错误"));
}
//更新返回数据框
m_strRecvData = pRecvData;
UpdateData(FALSE);
GetDlgItem(IDC_BTN_SEND)->EnableWindow(TRUE);
}
void CUploadPhotoDlg::OnBtnFileopen()
{
// TODO: Add your control notification handler code here
TCHAR tzFilter[] = _T("jpg图片(*.jpg;*.jpeg)|*.jpg;*.jpeg|gif图片(*.gif)|*.gif|所有文件(*.*)|*.*||");
CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_ENABLESIZING|OFN_EXPLORER,
tzFilter,NULL);
if (dlg.DoModal() == IDOK)
{
m_strPhotoPath = dlg.GetPathName();
UpdateData(FALSE);
}
}
负载一个人的博客地址:http://blog.chinaunix.net/uid/10386087/frmd/140683.html
分享到:
相关推荐
用VC写了个MFC环境下的post数据类这次将这个类进行扩展,可以post图片。但这两个post所使用的方法不一样。
VC编写自己构造http协议数据的post上传图片类 文档说明
本资源是一个封装类,采用异步方式解决了Wininet不能设置超时的问题,当前异步采用C++11线程库及同步方式,可修改为MFC工作线程后在VS2012以下版本使用。JSON解析库采用JSONCPP。调用方式参考: CWininetHttp MyHttp...
VC代码实现GBK和汉字相互转换的小工具,方便编码和汉字的相互转换,其中也包含了bcd编码和asc编码相互转换的算法。
VC WinInet API/MFC编写 通过PUT方式上传数据
CHttpClient HttpRequest;... //注意 这里返回的json数据 如果是中文的话,是 编码模式存在的,可以用jsoncppp解析,解析出来默认就是中文。 ::MessageBoxA(NULL,"JSON数据 记事本写入成功" ,"提示",MB_OK);
通过调用封装API函数WideCharToMultiByte和MultiByteToWideChar,实现ANSI/UTF-8/Unicode编码格式的相互转换。有C++和C两个版本。
1.可以将字符(包括中文和英文)和Unicode相互转换。2.将正整数转化为八进制、二进制、十进制、十六进制。3.键盘钩子,根据按键,显示字符、ACS码值、二进制数值。编译环境VC++6.0,系统:windows xp SP3
VC/MFC实现简单的Http服务器(可访问图片和网站内页)
在VC6.0中使用MFC实现Excel自动化:写入数据绘制图表 环境说明: Windows XP VC++ 6.0 Excel 2003 详细过程: http://zhangliancheng.com
MFC联合Halcon实现一些画点划线的功能,同时包含VC和Halcon之间的数据转换
VC中几种数据类型之间的转换,比如Unicode字符集下,1、 Char* 转为 CString; CString 转 const char*等
VC 2015 MFC 图片列表ListCtrl
在MFC通信模块中经常会遇到数据类型的转换,比如会收到下位机的数据(如:10 20 30 40 64 DD ),需要在Dailog中显示'0x64'为'100 Dec',那必须先从CString >> HEX>>DEC>> CString 实行代码如下: CString readData...
计算机图形学——立方体旋转 VC MFC
环境:vc6 基于对话框,在CEDIT框中实现进制间转换,也就是实现转换并且显示到CEDIT控件上。 已实现的功能:二进制与十六进制字符串之间的转换。 未实现的功能:二进制与ASCII、十六进制与ASCII字符串之间的转换。...
MFC程序中通过HttpGet和HttpPost方式向WebService发送请求,WebService以Json的方式返回数据,MFC程序解析Json,得到指定数据。
功能强大的VC访问HTTP类。 实现了HTTP的GET、POST和图片下载方法。能自动提取和保存返回的cookies,在发送数据包时能自动添加保存好的cookies。能自动识别网站的编码,在接收数据后,自动将编码转换。在发送数据时...
上课时的课件,VC6.0中MFC写的,可以即时显示,分享一下,希望对大家有帮助
MFC程序设计详细实例 第29章 VC2005 MFC编程环境MFC程序设计详细实例 第29章 VC2005 MFC编程环境MFC程序设计详细实例 第29章 VC2005 MFC编程环境MFC程序设计详细实例 第29章 VC2005 MFC编程环境MFC程序设计详细实例 ...