Pregunta

¿Cómo subo un archivo a un servidor web usando c ++ y MFC? No estamos utilizando .Net. ¿Necesitaría abrir un socket y hacer todo por mí mismo? Si es así, ¿a dónde debe seguir una buena referencia?

¿Fue útil?

Solución

No quieres usar llamadas de socket directas. Es difícil obtener HTTP de esta manera.

La forma más fácil es a través de las API de WinINet. Echa un vistazo a los documentos de InternetOpen, esta será probablemente la primera llamada que hagas. Funciones que probablemente necesitará:

  • InternetOpen
  • InternetConnect
  • HttpOpenRequest
  • HttpSendRequest
  • HttpQueryInfo
  • InternetCloseHandle

Puede encontrar documentos para todos estos en msdn

Otros consejos

Aquí está el código que terminé usando. Quité la comprobación de errores, y otras cosas de notificación. Esto hace que se cargue un formulario de varias partes.

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;

} 

WinInet como se sugiere. Tenga en cuenta que hay clases MFC que envuelven estas API. Si, por algún motivo, estas API no son flexibles para sus requisitos (por ejemplo, necesita implementar la conexión a través de un proxy que incluya autenticación), analice WinHTTP. Es un superconjunto de WinInet (aunque no hay envoltorios MFC para WinHTTP).

También puede utilizar XMLHTTP. Incluso si no estás enviando XML. Basado en WinINet, pero un poco más fácil de usar (si está acostumbrado a trabajar con COM de todos modos).
Consulte MSDN: http://msdn.microsoft.com/en-us/library /ms759148.aspx

Si tienes un servidor ftp, revisa la clase CFtpConnection.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top