MFC 文件上传

Posted

技术标签:

【中文标题】MFC 文件上传【英文标题】:MFC File upload 【发布时间】:2008-10-01 18:03:09 【问题描述】:

如何使用 c++ 和 MFC 将文件上传到网络服务器。我们没有使用.Net。我需要打开一个套接字并自己做所有事情吗?如果是这样,在哪里可以参考?

【问题讨论】:

【参考方案1】:

您不想使用直接套接字调用。以这种方式很难正确获取 HTTP。

更简单的方法是使用 WinINet API。查看 InternetOpen 的文档,这可能是您拨打的第一个电话。您可能需要的功能:

互联网开放 互联网连接 HttpOpenRequest HttpSendRequest HttpQueryInfo Internet 关闭句柄

您可以在 msdn 上找到所有这些的文档

【讨论】:

【参考方案2】:

这是我最终使用的代码。我去掉了错误检查和其他通知内容。这会进行多部分表单上传。

DWORD dwTotalRequestLength;
DWORD dwChunkLength;
DWORD dwReadLength;
DWORD dwResponseLength;
CHttpFile* pHTTP = NULL;

dwChunkLength = 64 * 1024; 
void* pBuffer = malloc(dwChunkLength);
CFile file ;

CInternetSession session("sendFile");
CHttpConnection *connection = NULL;

try 
//Create the multi-part form data that goes before and after the actual file upload.

CString strHTTPBoundary = _T("FFF3F395A90B452BB8BEDC878DDBD152");       
CString strPreFileData = MakePreFileData(strHTTPBoundary, file.GetFileName());
CString strPostFileData = MakePostFileData(strHTTPBoundary);
CString strRequestHeaders = MakeRequestHeaders(strHTTPBoundary);
dwTotalRequestLength = strPreFileData.GetLength() + strPostFileData.GetLength() + file.GetLength();

connection = session.GetHttpConnection("www.YOURSITE.com",NULL,INTERNET_DEFAULT_HTTP_PORT);

pHTTP = connection->OpenRequest(CHttpConnection::HTTP_VERB_POST, _T("/YOUURL/submit_file.pl"));
pHTTP->AddRequestHeaders(strRequestHeaders);
pHTTP->SendRequestEx(dwTotalRequestLength, HSR_SYNC | HSR_INITIATE);

//Write out the headers and the form variables
pHTTP->Write((LPSTR)(LPCSTR)strPreFileData, strPreFileData.GetLength());

//upload the file.

dwReadLength = -1;
int length = file.GetLength(); //used to calculate percentage complete.
while (0 != dwReadLength)

    dwReadLength = file.Read(pBuffer, dwChunkLength);
    if (0 != dwReadLength)
    
    pHTTP->Write(pBuffer, dwReadLength);
    


file.Close();

//Finish the upload.
pHTTP->Write((LPSTR)(LPCSTR)strPostFileData, strPostFileData.GetLength());
pHTTP->EndRequest(HSR_SYNC);


//get the response from the server.
LPSTR szResponse;
CString strResponse;
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();


AfxMessageBox(strResponse);

//close everything up.
pHTTP->Close();
connection->Close();
session.Close();

CString CHelpRequestUpload::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 CHelpRequestUpload::MakePreFileData(CString& strBoundary, CString& strFileName)

CString strFormat;
CString strData;

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

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

strFormat += _T("--%s");
strFormat += _T("\r\n");
strFormat += _T("Content-Disposition: form-data; name=\"filename\"; filename=\"%s\"");
strFormat += _T("\r\n");
strFormat += _T("Content-Type: audio/x-flac");
strFormat += _T("\r\n");
strFormat += _T("Content-Transfer-Encoding: binary");
strFormat += _T("\r\n\r\n");

strData.Format(strFormat, strBoundary, m_Name, strBoundary, m_Email,  strBoundary, strFileName);

return strData;
 

CString CHelpRequestUpload::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=\"submitted\"");
strFormat += _T("\r\n\r\n");
strFormat += _T("");
strFormat += _T("\r\n");
strFormat += _T("--%s--");
strFormat += _T("\r\n");

strData.Format(strFormat, strBoundary, strBoundary);

return strData;

 

【讨论】:

【参考方案3】:

建议的 WinInet。请记住,有包装这些 API 的 MFC 类。 如果由于某种原因这些 API 不能灵活地满足您的要求(例如,您需要通过代理实现连接,包括身份验证),请查看 WinHTTP。它是 WinInet 的超集(尽管没有用于 WinHTTP 的 MFC 包装器)。

【讨论】:

【参考方案4】:

您可以使用 BITS:

http://www.codeproject.com/KB/IP/bitsman.aspx

【讨论】:

【参考方案5】:

您也可以使用 XMLHTTP。即使您不发送 XML。基于 WinINet 构建,但更易于使用(如果您习惯使用 COM)。 见 MSDN:http://msdn.microsoft.com/en-us/library/ms759148.aspx

【讨论】:

【参考方案6】:

如果您有 ftp 服务器,请查看 CFtpConnection 类。

【讨论】:

我需要的不仅仅是文件。我还需要一些用户输入的字段。

以上是关于MFC 文件上传的主要内容,如果未能解决你的问题,请参考以下文章

MFC之HTTP文件上传

mfc 链接 access 2007 数据库

VS2013+MFC串口控件的简单上位机

实例详解:MFC坐标轴实现

在MFC中,如何读取外部的位图文件,让它显示在图片控件(Picture Control)中?

在 MFC 中使用 WinINet 的问题