WinInet模拟HTTP POST上传二进制文件流

dimply 2014-06-18 12:19:26
BOOL CDllValidateDlg::PostHttpPage(CString &result,CString &PageName,CString &postData) // 请求Http.
{
CInternetSession session("SighAgent");
try
{
INTERNET_PORT nPort = 80;
DWORD dwRet = 0;

/*以下为wininet 网络请求流程*/
CHttpConnection* pServer = session.GetHttpConnection(SERVER_IP, nPort);
CHttpFile* pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_POST,PageName); //打开一个请求
CString strHeaders = "Content-Type: application/x-www-form-urlencoded"; // 请求头

//开始发送请求

string data_post = MultiByteToUtf8(postData.GetBuffer(0));
pFile->SendRequest(strHeaders,(LPVOID)data_post.data(),data_post.size()); //发送请求,注意此为堵塞函数
pFile->QueryInfoStatusCode(dwRet); //发送请求后,就查询发送的结果

if (dwRet == HTTP_STATUS_OK) //这个代表请求正确
{
CString str;
while(pFile->ReadString(str)) //开始返回返回结果
{
char *pStr = (char*)str.GetBuffer(str.GetLength()); //取得str对象的原始字符串
result = result + str;
}
result = Utf8ToMultiByte(result.GetBuffer(0)).c_str();
}
else
{
SAFE_DELETE(pFile);
SAFE_DELETE(pServer);
return FALSE;
}

SAFE_DELETE(pFile);
SAFE_DELETE(pServer);
}
catch (CInternetException* pEx)
{
//catch errors from WinInet
TCHAR pszError[200];
pEx->GetErrorMessage(pszError, 200);
OutputDebugString(pszError);
return FALSE;
}

session.Close();
return TRUE;
}

我在程序里用到上面这个PostHttpPage函数,来和服务器交互数据。
之前的一些数据上传都是字符串或整型数,没出现过问题。
现在想用这同一个函数,上传二进制形式的文件流,没有成功。请问我下面的做法是哪里错了?
//二进制导入图片文件
char buffer[102400]; //BUF_SIZE大小自己定义
FILE * pFile = fopen("photo.bmp", "rb");
int img = fread(buffer, sizeof(char), 102400, pFile);
// char stzimg[100];
// itoa(img,stzimg,10);
// AfxMessageBox(stzimg);
//二进制导入图片文件结束

CString post_data;
post_data.Format("matchid='%s'&matchname='%s'&aid='%d'&ticket='%d'"
"&name='%s'&gender='%d'&folk='%s'&birthday='%s'&addr='%s'&cardid='%s'&expire='%s'&agency='%s'&face='%s'",
matchID,matchName,AID,ticket,
Name,abs(stricmp(Gender,"女")),Folk,BirthDay,Address,Code, ExpireEnd, Agency,buffer); //请求的附加参数
CString result; //返回的结果
CString post_page = "test_id_validater/update_num.php"; //请求的php
PostHttpPage(result,post_page,post_data);

...全文
301 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuzuning 2014-06-19
  • 打赏
  • 举报
回复
c++ 应用 curl 库函数实现,这样少了协议的处理,事情变得单纯了 也可以用 sock 库函数实现 你 #3 的代码就是 sock 应用的一个例子
dimply 2014-06-19
  • 打赏
  • 举报
回复
引用 8 楼 xuzuning 的回复:
你是玩C的,你应该清楚的知道字符串是依靠尾部附加的 '\0' 来判断结束的,那你如何能保证图片数据中不出现'\0' 而导致字符串提前结束呢?
我其实并不知道确切该怎么做,所以随便套用了之前传递整型数的办法,知道是不对的。
xuzuning 2014-06-18
  • 打赏
  • 举报
回复
你是玩C的,你应该清楚的知道字符串是依靠尾部附加的 '\0' 来判断结束的,那你如何能保证图片数据中不出现'\0' 而导致字符串提前结束呢?
dimply 2014-06-18
  • 打赏
  • 举报
回复
引用 6 楼 oyljerry 的回复:
[quote=引用 4 楼 dimply 的回复:] 这应该是把文件以二进制形式传给test.php吧。那么在test.php那边怎么接收这个二进制,并写入mysql数据库的某个字段呢?
要看对应的php是如何处理的。然后你发送对应格式的数据[/quote] 对应PHP文件是用$bian_liang_ming = $_REQUEST['xxxx']; 来获取传过去的参数的。这种情况如何传递二进制数据流啊?
oyljerry 2014-06-18
  • 打赏
  • 举报
回复
引用 4 楼 dimply 的回复:
这应该是把文件以二进制形式传给test.php吧。那么在test.php那边怎么接收这个二进制,并写入mysql数据库的某个字段呢?
要看对应的php是如何处理的。然后你发送对应格式的数据
dimply 2014-06-18
  • 打赏
  • 举报
回复
它可以和别的整型数及字串在同一次post中提交吗?
dimply 2014-06-18
  • 打赏
  • 举报
回复
这应该是把文件以二进制形式传给test.php吧。那么在test.php那边怎么接收这个二进制,并写入mysql数据库的某个字段呢?
dimply 2014-06-18
  • 打赏
  • 举报
回复
我在网上找到上传文件的代码是这个样子的:
  #include <windows.h>
  #include <wininet.h>
  #include <iostream>


  #define ERROR_OPEN_FILE       10
  #define ERROR_MEMORY          11
  #define ERROR_SIZE            12
  #define ERROR_INTERNET_OPEN   13
  #define ERROR_INTERNET_CONN   14
  #define ERROR_INTERNET_REQ    15
  #define ERROR_INTERNET_SEND   16

  using namespace std;

  int main()
  {
     // Local variables
     static char *filename   = "test.txt";   //Filename to be loaded
     static char *type       = "image/jpg";
     static char boundary[]  = "pippo";            //Header boundary
     static char nameForm[]  = "uploadedfile";     //Input form name
     static char iaddr[]     = "localhost";        //IP address
     static char url[]       = "test.php";         //URL

     char hdrs[255];                  //Headers
     char * buffer;                   //Buffer containing file + headers
     char * content;                  //Buffer containing file
     FILE * pFile;                    //File pointer
     long lSize;                      //File size
     size_t result;                   


     // Open file
     pFile = fopen ( filename , "rb" );
     if (pFile==NULL) return ERROR_OPEN_FILE;

     // obtain file size:
     fseek (pFile , 0 , SEEK_END);
     lSize = ftell (pFile);
     rewind (pFile);

     // allocate memory to contain the whole file:
     content = (char*) malloc (sizeof(char)*lSize);
     if (content == NULL) return ERROR_MEMORY;

     // copy the file into the buffer:
     result = fread (content,1,lSize,pFile);
     if (result != lSize) return ERROR_SIZE;

     // terminate
     fclose (pFile);

     //allocate memory to contain the whole file + HEADER
     buffer = (char*) malloc (sizeof(char)*lSize + 2048);

     //print header
     sprintf(hdrs,"Content-Type: multipart/form-data; boundary=%s",boundary);
     sprintf(buffer,"--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n",boundary,nameForm,filename);
     sprintf(buffer,"%sContent-Type: %s\r\n\r\n",buffer,type);
     sprintf(buffer,"%s%s\r\n",buffer,content);
     sprintf(buffer,"%s--%s--\r\n",buffer,boundary);

     //Open internet connection
     HINTERNET hSession = InternetOpen("WinSock",INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
     if(hSession==NULL) return ERROR_INTERNET_OPEN;

     HINTERNET hConnect = InternetConnect(hSession, iaddr,INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
     if(hConnect==NULL) return ERROR_INTERNET_CONN;

     HINTERNET hRequest = HttpOpenRequest(hConnect, (const char*)"POST",url, NULL, NULL, (const char**)"*/*\0", 0, 1);
     if(hRequest==NULL) return ERROR_INTERNET_REQ;

     BOOL sent= HttpSendRequest(hRequest, hdrs, strlen(hdrs), buffer, strlen(buffer));
     if(!sent) return ERROR_INTERNET_SEND;

     //close any valid internet-handles
     InternetCloseHandle(hSession);
     InternetCloseHandle(hConnect);
     InternetCloseHandle(hRequest);

     return 0;
  }
fishion 2014-06-18
  • 打赏
  • 举报
回复
你确定html协议是这样传二进制文件的吗,先用wireshark查看下
oyljerry 2014-06-18
  • 打赏
  • 举报
回复
二进制考虑用BASE64编码等,然后Post

21,886

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧