2

C++ と MFC を使用してファイルを Web サーバーにアップロードする方法を教えてください。.Net は使用していません。ソケットを開いてすべてを自分で行う必要がありますか? もしそうなら、従うべき良いリファレンスはどこですか?

4

6 に答える 6

5

直接ソケット呼び出しを使用したくない場合。この方法で HTTP を正しく取得するのは困難です。

簡単な方法は、WinINet API を使用することです。InternetOpen のドキュメントを確認してください。おそらくこれが最初の呼び出しになるでしょう。必要になる可能性が高い機能:

  • インターネット開く
  • インターネット接続
  • HttpOpenRequest
  • HttpSendRequest
  • HttpQueryInfo
  • InternetCloseHandle

msdn でこれらすべてのドキュメントを見つけることができます

于 2008-10-01T18:08:50.960 に答える
3

これが私が最終的に使用したコードです。エラーチェックやその他の通知を取り除きました。これは、マルチパート フォームのアップロードを行います。

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;

} 
于 2008-10-16T17:23:35.643 に答える
1

提案どおりのWinInet。これらの API をラップする MFC クラスがあることに注意してください。何らかの理由でこれらの API が要件に対して柔軟でない場合 (たとえば、認証を含むプロキシ経由の接続を実装する必要がある場合)、WinHTTP を見てください。これは WinInet のスーパーセットです (WinHTTP 用の MFC ラッパーはありません)。

于 2008-10-02T07:04:45.290 に答える
0

XMLHTTPを使用することもできます。XMLを送信していない場合でも。WinINetに基づいて構築されていますが、少し使いやすくなっています(とにかく、COMの操作に慣れている場合)。
MSDNを参照してください:http://msdn.microsoft.com/en-us/library/ms759148.aspx

于 2008-10-01T18:36:24.933 に答える
0

BITS を使用できます。

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

于 2008-10-01T18:10:13.563 に答える
0

ftp サーバーをお持ちの場合は、CFtpConnection クラスを確認してください。

于 2008-10-02T18:04:29.463 に答える