HTTP POST 요청을 사용하여 게임의 웹 사이트로 파일을 보내려고합니다. HTML 페이지의 양식을 사용하여 파일을 보내면 제대로 작동합니다. 그러나 게임 내에서 똑같은 것을 시뮬레이션 할 수 없었습니다. 요청이 성공적으로 완료되었음을 나타내는 200의 응답 코드가 수신되지만 업로드 스크립트는 GET 요청을 받았음을 나타내며 $ _FILES 및 $ _POST 배열은 비어 있습니다. 필자는 Wireshark에서 HTML 폼의 POST와 게임의 POST 결과를 살펴 보았지만 둘 사이의 의미있는 차이점을 발견하지 못했습니다. (HTML 폼의 POST 메서드를 정확히 복제하는 방법을 알고 있다면 가능 하겠지만 가능하지 않다고 생각합니다.)HTTP POST 요청이 제대로 작동하지 않습니다.
어쨌든 여기에 코드를 보내고 있습니다. 감사!
HINTERNET hInternet;
HINTERNET hConnect;
HINTERNET hRequest;
INTERNET_BUFFERS Buffers;
DWORD dwBytesWritten;
DWORD dwNumBytesToWrite;
char szBoundary[32];
char szContentTypeHeader[64];
char szFileHeader[256];
char szFileFooter[4];
char szBodyFooter[32];
ULONG ulTotalBytesWritten;
ULONG ulOffset;
ULONG ulContentLength;
// Get a handle for working with the Internet.
hInternet = InternetOpen("Wrack", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hInternet == NULL)
return (false);
// Open an HTTP session for the site.
hConnect = InternetConnect(hInternet, "wrackgame.com", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, NULL);
if (hConnect == NULL)
{
InternetCloseHandle(hInternet);
return (false);
}
// Open the POST request.
hRequest = HttpOpenRequest(hConnect, "POST", "leaderboard/upload_file.php", NULL, "http://www.wrackgame.com/leaderboard/upload.html", NULL, 0, NULL);
if (hRequest == NULL)
{
InternetCloseHandle(hInternet);
InternetCloseHandle(hConnect);
return (false);
}
// Generate our various headers and footers.
sprintf_s(szBoundary, "----%04x%04x%04x", rand() % 0xffff, rand() % 0xffff, rand() % 0xffff);
sprintf_s(szContentTypeHeader, "Content-Type: multipart/form-data; boundary=%s", szBoundary);
sprintf_s(szFileHeader, "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\nContent-Type: application/octet-stream\r\n\r\n", szBoundary, "file", "testreplay.wrp");
sprintf_s(szFileFooter, "\r\n");
sprintf_s(szBodyFooter, "--%s--\r\n", szBoundary);
// Build our header.
if (HttpAddRequestHeaders(hRequest, szContentTypeHeader, -1, HTTP_ADDREQ_FLAG_ADD) == false)
{
InternetCloseHandle(hInternet);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
return (false);
}
// Calculate how much data we'll be sending.
ulContentLength = network_CalcContentLength(szFileHeader, szFileFooter, szBodyFooter);
// Initialize our buffers.
memset(&Buffers, 0, sizeof(INTERNET_BUFFERS));
Buffers.dwStructSize = sizeof(INTERNET_BUFFERS);
Buffers.dwBufferTotal = ulContentLength;
// Send our HTTP request.
if (HttpSendRequestEx(hRequest, &Buffers, NULL, HSR_INITIATE, NULL) == false)
{
InternetCloseHandle(hInternet);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
return (false);
}
// Send the header.
ulTotalBytesWritten = 0;
if (InternetWriteFile(hRequest, szFileHeader, strlen(szFileHeader), &dwBytesWritten) == false)
{
InternetCloseHandle(hInternet);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
return (false);
}
ulTotalBytesWritten += dwBytesWritten;
// Next, write the body of the replay.
ulOffset = 0;
while (ulOffset < (DWORD)REPLAY_GetReplaySize())
{
// Determine how many bytes of the replay to send. If we're almost
// done, send less than 1024 bytes.
dwNumBytesToWrite = min(1024, REPLAY_GetReplaySize() - ulOffset);
// Send a piece of the replay and log how many bytes we actually
// transferred.
if (InternetWriteFile(hRequest, REPLAY_GetReplayData() + ulOffset, dwNumBytesToWrite, &dwBytesWritten) == false)
{
InternetCloseHandle(hInternet);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
return (false);
}
ulTotalBytesWritten += dwBytesWritten;
// Increment the offset of the replay buffer.
ulOffset += 1024;
}
// Send our file footer.
if (InternetWriteFile(hRequest, szFileFooter, strlen(szFileFooter), &dwBytesWritten) == false)
{
InternetCloseHandle(hInternet);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
return (false);
}
ulTotalBytesWritten += dwBytesWritten;
// Send our body footer.
if (InternetWriteFile(hRequest, szBodyFooter, strlen(szBodyFooter), &dwBytesWritten) == false)
{
InternetCloseHandle(hInternet);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
return (false);
}
ulTotalBytesWritten += dwBytesWritten;
// Close our request now that we're done.
if (HttpEndRequest(hRequest, NULL, 0, NULL) == false)
{
InternetCloseHandle(hInternet);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
return (false);
}
InternetCloseHandle(hInternet);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
// No need to do anything more!
return (true);
도움이 될지 모르겠지만 개별 청크가 아닌 데이터 블록 하나를 작성해 보았습니까? – Deanna
@Deanna : 어떻게해야합니까? 내가 아는 한, HttpSendRequest와 같은 프로세스를 시작하기 위해 여러 함수를 사용해야한다. HttpSendRequest는 InternetWriteFile을 사용하여 본문을 보내기 전에 패킷을 보낸다. – Carnevil
프로세스를 시작하려면 예, 그렇지만 적어도 InternetWriteFile()에 4 번 이상 호출하면 문제의 원인이 될 수 있습니다. – Deanna