问题描述
我有此代码,但无法正常工作。我通过Postman进行了测试,PHP可以正确获取数据。问题出在C ++中,它没有通过POST发送文件。怎么了?
这个想法是让DLL生成.txt
文件并将其发布到PHP,PHP将在其中接收并将其插入数据库。
void PHP_Autentication (void){
static TCHAR frmdata[] = "-----------------------------og94kfkldjs7ekk\r\nContent-disposition: form-data; name=\"arquivo\"; filename=\"g.txt\"\r\nContent-Type: text/plain\r\n\r\nCodex Anti-Hack\r\n-----------------------------og94kfkldjs7ekk--\r\n";
static TCHAR hdrs[] = "Content-Type: multipart/form-data; boundary=---------------------------og94kfkldjs7ekk";
HINTERNET hSession = Internetopen("Mybrowser",INTERNET_OPEN_TYPE_PRECONfig,NULL,0);
if(!hSession)
{
PHP_DC();
}
HINTERNET hConnect = InternetConnect(hSession,_T (carrega.IP_Server_and_Hard),INTERNET_DEFAULT_HTTP_PORT,INTERNET_SERVICE_HTTP,1);
if(!hConnect)
{
PHP_DC();
}
LPCTSTR rgpszAcceptTypes[] = {_T("*/*"),NULL};
HINTERNET hRequest = HttpOpenRequest(hConnect,(const char*)"POST",_T("sentinela/sentinela.PHP"),rgpszAcceptTypes,1);
if(hRequest==NULL)
{
PHP_DC();
}
BOOL sent= HttpSendRequest(hRequest,hdrs,strlen(hdrs),frmdata,strlen(frmdata));
if(!sent)
{
PHP_DC();
}
char buffer[2048] = {};
DWORD bufferSize = sizeof(buffer);
BOOL success = HttpQueryInfo(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF,buffer,&bufferSize,NULL);
if(!success)
{
PHP_DC();
}
std::cout << buffer << std::endl;
ZeroMemory(buffer,sizeof(buffer));
success = InternetReadFile(hRequest,sizeof(buffer),&bufferSize);
if(!success)
{
PHP_DC();
}
else
{
InternetCloseHandle(hSession);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
}
}
<?PHP
session_start();
define('HOST','111.111.111.111');
define('USUARIO','user');
define('SENHA','pass');
define('DB','db');
$conexao = MysqLi_connect(HOST,USUARIO,SENHA);
$db_select = MysqLi_select_db($conexao,DB);
$arquivo_tmp = $_FILES['arquivo']['tmp_name'];
$dados = file($arquivo_tmp);
foreach($dados as $linha){
var_dump($dados);
$mac = $dados[0];
$serial = $dados[1];
$namepc = $dados[2];
$idgame = $dados[3];
$ip = $dados[4];
$userpc = $dados[5];
}
$sql = "INSERT INTO log (id,user,mac_addr,serial,uName,ip,date) VALUES ('NULL','$idgame','$mac','$serial','$namepc','$ip',Now())";
MysqLi_query($conexao,$sql);
?>
要在POST中发送的文件是.txt
,其中包含:
00:00:AA:AA:00:00 123456789 DESKTOP-11111 123456789 192.168.0.0 Jhon
解决方法
您根本没有发送.txt
文件。您将在其位置发送硬编码字符串"Codex Anti-Hack"
。
要发送实际的.txt
文件,您可以:
- 动态分配整个MIME数据缓冲区,填充它,然后将其传递给
HttpSendRequest()
。在运行时查询文件大小,以了解分配缓冲区的大小。例如:
#include <vector>
#include <memory>
#include <algorithm>
#include <type_traits>
struct HINTERNET_deleter
{
using pointer = HINTERNET;
// in VC2010: use this instead:
// typedef HINTERNET pointer;
void operator()(HINTERNET hInternet) const { InternetCloseHandle(hInternet); }
};
using HINTERNET_ptr = std::unique_ptr<std::remove_pointer<HINTERNET>::type,HINTERNET_deleter>;
// in VC2010: use this instead:
// typedef std::unique_ptr<std::remove_pointer<HINTERNET>::type,HINTERNET_deleter> HINTERNET_ptr;
struct HFILE_deleter
{
using pointer = HANDLE;
// in VS2010,use this instead:
// typedef HANDLE pointer;
void operator()(HANDLE hFile) const { if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); }
};
using HFILE_ptr = std::unique_ptr<std::remove_pointer<HANDLE>::type,HFILE_deleter>;
// in VS2010,use this instead:
// typedef std::unique_ptr<std::remove_pointer<HANDLE>::type,HFILE_deleter> HFILE_ptr;
bool PHP_Autentication()
{
static char frmdata_1[] = "-----------------------------og94kfkldjs7ekk\r\n"
"Content-Disposition: form-data; name=\"arquivo\"; filename=\"g.txt\"\r\n"
"Content-Type: text/plain\r\n"
"\r\n";
static DWORD frmdata_1_len = sizeof(frmdata_1) - 1;
static char frmdata_2[] = "\r\n"
"-----------------------------og94kfkldjs7ekk--\r\n";
static DWORD frmdata_2_len = sizeof(frmdata_2) - 1;
static TCHAR hdrs[] = "Content-Type: multipart/form-data; boundary=---------------------------og94kfkldjs7ekk";
static DWORD hdrs_len = (sizeof(hdrs) / sizeof(hdrs[0])) - 1;
HFILE_ptr hFile( CreateFile(_T("path\\filename.txt"),GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL) );
if (hFile.get() == INVALID_HANDLE_VALUE)
{
// error handling...
return false;
}
DWORD dwFileSize = GetFileSize(hFile.get(),NULL);
if (dwFileSize == INVALID_FILE_SIZE)
{
// error handling...
return false;
}
std::vector<char> frmdata(frmdata_1_len + dwFileSize + frmdata_2_len);
std::copy_n(frmdata_1,frmdata_1_len,&frmdata[0]);
DWORD dwOffset = frmdata_1_len;
while (dwFileSize > 0)
{
DWORD dwNumRead;
if ((!ReadFile(hFile.get(),&frmdata[dwOffset],dwFileSize,&dwNumRead,NULL)) || (dNumRead == 0))
{
// error handling...
return false;
}
dwOffset += dwNumRead;
dwFileSize -= dwNumRead;
}
std::copy_n(frmdata_2,frmdata_2_len,&frmdata[dwOffset]);
HINTERNET_ptr hSession( InternetOpen(_T("MyBrowser"),INTERNET_OPEN_TYPE_PRECONFIG,0) );
if (!hSession)
{
// error handling...
return false;
}
HINTERNET_ptr hConnect( InternetConnect(hSession.get(),carrega.IP_Server_and_Hard,INTERNET_DEFAULT_HTTP_PORT,INTERNET_SERVICE_HTTP,1) );
if (!hConnect)
{
// error handling...
return false;
}
LPCTSTR rgpszAcceptTypes[] = {_T("*/*"),NULL};
HINTERNET_ptr hRequest( HttpOpenRequest(hConnect.get(),_T("POST"),_T("sentinela/sentinela.php"),rgpszAcceptTypes,1) );
if (!hRequest)
{
// error handling...
return false;
}
if (!HttpSendRequest(hRequest.get(),hdrs,hdrs_len,frmdata.data(),frmdata.size()))
{
// error handling...
return false;
}
DWORD dwStatusCode,dwIndex = 0;
if (!HttpQueryInfo(hRequest.get(),HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,&dwStatusCode,sizeof(dwStatusCode),&dwIndex))
{
// error handling...
return false;
}
TCHAR buffer[2048] = {};
DWORD bufferSize = sizeof(buffer);
dwIndex = 0;
if (!HttpQueryInfo(hRequest.get(),HTTP_QUERY_RAW_HEADERS_CRLF,buffer,&bufferSize,&dwIndex))
{
// error handling...
return false;
}
#ifdef UNICODE
std::ostream &t_cout = std::wcout;
#else
std::ostream &t_cout = std::cout;
#endif
t_cout.write(buffer,bufferSize / sizeof(TCHAR));
t_cout << std::endl;
return ((dwStatusCode / 100) == 2);
}
- 使用
HttpSendRequestEx()
代替HttpSendRequest()
,以便可以使用ReadFile()
和InternetWriteFile()
在MIME数据中间以块的形式发送文件数据。例如:
#include <vector>
#include <memory>
#include <algorithm>
#include <type_traits>
struct HINTERNET_deleter
{
using pointer = HINTERNET;
// in VC2010: use this instead:
// typedef HINTERNET pointer;
void operator()(HINTERNET hInternet) const { InternetCloseHandle(hInternet); }
};
using HINTERNET_ptr = std::unique_ptr<std::remove_pointer<HINTERNET>::type,HFILE_deleter> HFILE_ptr;
bool WriteToInet(HINTERNET hRequest,LPCVOID buffer,DWORD size)
{
LPCBYTE ptr = (LPCBYTE) buffer;
DWORD dwNumWritten;
while (size > 0)
{
if (!InternetWriteFile(hRequest,ptr,size,&dwNumWritten))
return false;
ptr += dwNumWritten;
size -= dwNumWritten;
}
return true;
}
bool PHP_Autentication()
{
static char frmdata_1[] = "-----------------------------og94kfkldjs7ekk\r\n"
"Content-Disposition: form-data; name=\"arquivo\"; filename=\"g.txt\"\r\n"
"Content-Type: text/plain\r\n"
"\r\n";
static DWORD frmdata_1_len = sizeof(frmdata_1)-1;
static char frmdata_2[] = "\r\n"
"-----------------------------og94kfkldjs7ekk--\r\n";
static DWORD frmdata_2_len = sizeof(frmdata_2)-1;
static TCHAR hdrs[] = "Content-Type: multipart/form-data; boundary=---------------------------og94kfkldjs7ekk";
static DWORD hdrs_len = (sizeof(hdrs) / sizeof(hdrs[0])) - 1;
HFILE_ptr hFile( CreateFile(_T("path\\filename.txt"),NULL);
if (dwFileSize == INVALID_FILE_SIZE)
{
// error handling...
return false;
}
HINTERNET_ptr hSession( InternetOpen(_T("MyBrowser"),INTERNET_FLAG_NO_CACHE_WRITE,1) );
if (!hRequest)
{
// error handling...
return false;
}
INTERNET_BUFFERS buf;
ZeroMemory(&buf,sizeof(buf));
buf.dwStructSize = sizeof(buf);
buf.lpcszHeader = hdrs;
buf.dwHeadersLength = hdrs_len;
buf.dwHeadersTotal = hdrs_len;
buf.lpvBuffer = NULL;
buf.dwBufferLength = 0;
buf.dwBufferTotal = frmdata_1_len + dwFileSize + frmdata_2_len;
buf.dwOffsetLow = 0;
buf.dwOffsetHigh = 0;
if (!HttpSendRequestEx(hRequest.get(),&buf,1))
{
// error handling...
return false;
}
if (!WriteToInet(hRequest.get(),frmdata_1,frmdata_1_len))
{
// error handling...
return false;
}
BYTE buffer[2048];
while (dwFileSize > 0)
{
DWORD dwNumRead;
if ((!ReadFile(hFile.get(),sizeof(buffer),NULL)) || (dwNumRead == 0))
{
// error handling...
return false;
}
if (!WriteToInet(hRequest.get(),dwNumRead))
{
// error handling...
return false;
}
dwFileSize -= dwNumRead;
}
if (!WriteToInet(hRequest.get(),frmdata_2,frmdata_2_len))
{
// error handling...
return false;
}
if (!HttpEndRequest(hRequest.get(),0))
{
// error handling...
return false;
}
DWORD dwStatusCode,bufferSize / sizeof(TCHAR));
t_cout << std::endl;
return ((dwStatusCode / 100) == 2);
}