2015-11-18 4 views
0

У меня есть следующий (урезанный) кусок коды:PHP fsockopen клиент не получает отправлен данные

function curl_request_async($url, $params) 
{ 
    foreach ($params as $key => $val) { 
     $post_params[] = $key.'='.urlencode($val); 
    } 
    $post_string = implode('&', $post_params); 

    $parts=parse_url($url); 

    $fp = fsockopen($parts['host'], 
     isset($parts['port'])?$parts['port']:80, 
     $errno, $errstr, 30); 
    fwrite($fp, "$type ".$parts['path']." HTTP/1.1\r\n"); 
    fwrite($fp, "Host: ".$parts['host']."\r\n"); 
    fwrite($fp, "Content-Type: application/x-www-form-urlencoded\r\n"); 
    fwrite($fp, "Content-Length: ".strlen($post_string)."\r\n"); 
    fwrite($fp, "Connection: Close\r\n\r\n"); 

    $bytes_written = fwrite($fp, $post_string); 
    var_dump($bytes_written, strlen($post_string)); 
    // fread($fp, 1); 
    // fflush($fp); 
    fclose($fp); 
} 

Проблема с этим кодом является то, что я не нашел никаких доказательств запроса достиг серверов с именем. Строка var_dump($bytes_written, strlen($post_string)); вышла int(493) int(493), поэтому она должна была получить все данные, но это не так.

Если у меня возникли проблемы с работой fread($fp, 1);, это работает без проблем. Это может быть рабочим решением, но, похоже, это не имеет смысла. Там должен быть лучший путь!

Мой вопрос тогда двоякий: почему fread($fp, 1); исправить мою проблему и есть ли лучшее решение?

+0

Не пытайтесь написать свой собственный клиентый HTTP в PHP, если вы не очень компетентны в обеих технологиях и имеет несколько месяцев пощадить работать на это полное время , Просто перечисление ошибок в коде, который вы представили, выйдет за рамки ответа здесь. Используйте завиток. Я знаю, что документация по PHP плохо, но документы библиотеки C немного лучше, и это работает. – symcbean

+0

@symcbean его не так сложно, если вы хотите поддерживать HTTPS и согласование содержимого и переадресацию и длину контента и все эти фантазии, конечно, но если вы просто собираетесь на простой клиент http GET, это не совсем жесткий. GET url \ r \ nheader1 \ r \ nheader2 \ r \ n \ r \ nbody ~ – hanshenrik

+0

@hansherik: глядя на код, который вы предоставили, он кажется вам сверх ваших способностей. Сокет TCP не является жестким. Пример, который вы указали выше, еще шире от марки, чем код Лекса. – symcbean

ответ

0

fread нуждается в двух параметрах: ресурсе и количестве байтов для чтения. Сейчас вы читаете только 1 байт. fread($fp, 1);

Если вы хотите, чтобы прочитать полный результат, петля, пока не прочитанные полностью:

while(!feof($fp)){ 
    echo fread($fp, 128); 
} 
1

ваша проблема, вероятно, что вы писали код сервера в PHP, и вы не имеете ignore_user_abort = TRUE по умолчанию (см. http://php.net/manual/en/misc.configuration.php#ini.ignore-user-abort), поэтому, когда вы закрываете соединение, ваш сервер перестает выполнять ваш php-код, таким образом, fread (fp, 1) исправить вашу проблему - соединение не закрывается, прежде чем php начнет писать ответ

Вы можете использовать этот код, чтобы сделать сервер для проверки, действительно ли он подключен или нет -

<?php 
error_reporting(E_ALL); 
ini_set('display_errors',1); 
$sck=socket_create(AF_INET,SOCK_STREAM,SOL_TCP); 
if($sck===FALSE){ 
    die('socket_create failed!'); 
} 
if(!socket_set_block($sck)){ 
    die("socket_set_block failed!"); 
} 
if(!socket_bind($sck, '0.0.0.0',1337)){ 
    die("FAILED to bind to port 1337"); 
} 
if(!socket_listen($sck,0)){ 
    die("socket_listen failed!"); 
} 
$fullFile=''; 
while((print('listening for connections!'.PHP_EOL)) && false!==($conn=socket_accept($sck))){ 
    echo "new connection!".PHP_EOL; 
    echo "generating crypto iv.."; 

    while(false!==($buffi=socket_recv($conn,$buff,1024,MSG_WAITALL))){ 
     if($buffi===0){ 
      break;//socket_recv's way of 
      //saying that the connection closed, 
      //apparently. the docs say it should return 
      // false, but it doesn't, it just infinitely returns int(0). 
      // at least on windows 7 x64 sp1. 
     } 
     $fullFile.=$buff; 
     echo "recieved ".strlen($fullFile)." bytes...".PHP_EOL; 
     $buff='';//do i need to clear it? or wiill recv do it for me? 
    } 
    echo "all bytes recieved (i guess, todo, socket_last_error confirm)."; 
    echo PHP_EOL;var_dump($fullFule); 
    echo "done!".PHP_EOL; 
} 

die("should never reach this code..."); 

это сделает сервер Netcat стиля на http://127.0.0.1:1337

Смежные вопросы