无法使HTTP POST请求正常工作

我正在尝试使用HTTP POST请求从我正在使用的游戏中发送文件到游戏的网站。 当我使用HTML页面上的表单发送文件时,它工作正常。 但是,我无法在游戏中模拟同样的事情。 我收到响应代码200表示请求成功,但是,上传脚本表明它收到了GET请求,$ _FILES和$ _POST数组为空。 我已经查看了HTML表单的POST和Wireshark中的游戏POST的输出,但是无法检测到两者之间有任何有意义的差异。 (如果我知道如何完全复制HTML表单的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 ); 

我之前试图回答这个问题,但我猜它没有通过。 无论如何,我觉得很傻。 它现在运作得很好。 它无法工作的原因是因为我将InternetOpen()的第二个参数称为“wrackgame.com”,而不是“www.wrackgame.com”。 我不知道为什么阻止它工作 – 特别是考虑到我的上传脚本/leaderboard/upload_file.php正在执行。 这不像流量没有到达服务器。 奇怪。

无论如何,感谢大家的帮助!

我不熟悉WinINet lib,但libcurl有一个c接口,包括一些关于如何设置HTTP POST请求的简单示例