PHP & C ++ Получение IP-адреса пользователя - PullRequest
0 голосов
/ 25 февраля 2011

У меня есть консольное приложение C ++, которое использует wininet.h для перехода по URL-адресу и загрузки содержимого веб-страницы.

Содержимое обычно представляет собой один IP-адрес.Это здесь: http://www.whatismyip.com/automation/n09230945.asp

Все отлично работает.

Тогда я решил создать свою собственную программу проверки IP в PHP, используя следующий код:

<?php

$ip = $_SERVER['REMOTE_ADDR'];

header("Cache-Control: private");
header("Content-Type: text/html");

echo $ip;

?>

Thisв браузере выглядит корректно, совпадает с результатами whatismyip.com, но программа на C ++ просто добавляет кучу мусора после IP, затем повторяет половину обрезанного IP, а затем добавляет еще больше мусора.

Что вызывает это?Я попытался проанализировать заголовки, но я не могу определить разницу.

Кроме того, я попытался поместить простой текстовый файл на сервер, и программа на C ++ прекрасно его читает.

Iтакже попытался изменить мои заголовки как обычный / текст и текст / обычный.Тот же результат.

Спасибо за вашу помощь!

Редактировать: Вот часть кода C ++:

HINTERNET OpenAddress = InternetOpenUrl(connect,"http://www...", NULL, 0, INTERNET_FLAG_PRAGMA_NOCACHE|INTERNET_FLAG_KEEP_CONNECTION, 0);

char DataReceived[16] = " ";
DWORD NumberOfBytesRead = 0;
while (InternetReadFile(OpenAddress, DataReceived, 16, &NumberOfBytesRead) &&     NumberOfBytesRead)
{
     cout << DataReceived;
}

Ответы [ 2 ]

1 голос
/ 15 ноября 2013
<?PHP
$ip = $_SERVER['REMOTE_ADDR']; //Checks internet remote adderater,
$fh = "YourSecretFileHere.txt"; //Starts a socket in w_temppTXT, aka the .txt
fwrite($fh, 'IP Address:'.'$ip'); //Writes Info From IP into File, 
fclose($fh); //Closes file, ends writing boot comp.
if $fh = ""; { //If the file is empty,
echo "IP File Is Empty!"; //Echo's From Above ^
else {
echo ""; //Prints nothing from variables
     }
?>
1 голос
/ 26 февраля 2011

cout ожидает, что строка будет оканчиваться нулем. Поскольку вы просто читаете байты в буфер, а не завершаете их нулем в конце, cout будет переноситься после конца прочитанных байтов и просто продолжит выгрузку памяти, пока не достигнет нулевого указателя или защита памяти срабатывает.

С вашим кодом происходит следующее:

  1. Вы назначаете 16-байтовую область памяти.
  2. Вы звоните InternetReadFile. Это помещает IP-адрес, скажем, «127.0.0.1» в ваш буфер, без нулевого терминатора.
  3. Вы звоните cout с DataReceived. Это массив символов, поэтому cout ожидает, что это строка с нулевым символом в конце. Он выводит каждый символ с начала буфера, сразу после «127.0.01» и далее, пока не найдет 0 в памяти.
  4. Поскольку «127.0.0.1» - это все, что нужно прочитать, и ваш буфер был больше этого, следующий вызов InternetReadFile оставляет NumberOfBytesRead равным нулю, поэтому ваш цикл происходит только один раз.

Ничего не знаю о InternetReadFile(), но я думаю, что такой подход должен работать, если вы берете только одну строку с IP-адресом в ней:

char DataReceived[64]; // I guess I'm antsy about having plenty of room

DWORD NumberOfBytesRead = 0;
if (InternetReadFile(OpenAddress, DataReceived, 63, &NumberOfBytesRead)) {
  DataReceived[NumberOfBytesRead] = '\0';
  cout << DataReceived;
} else // handle error condition

Но, по сути, я думаю, что основная проблема, с которой вы столкнулись, заключается в том, что вы путаете буфер, который представляет собой просто набор байтов, с приятной дружественной строкой с нулевым символом в конце, и вы должны это понимать, и, возможно, искать некоторые существующие примеры использования InternetReadFile с учетом этого, чтобы увидеть, как они работают, и, следовательно, что вам нужно сделать.

...