Неблокирующий fsockopen

12 3
К
На сайте с 03.02.2005
Offline
74
1986

Здравствуйте, Уважаемые!

Столкнулся с проблемой при использовании неблокирующих сокетов. Если с вашей помощью получится найти решение буду премного благодарен.

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

Насколько я понимаю, все аналогичные fsockopen решения (например, функция stream_socket_client, низкоуровневый сокет-интерфейс или использование cURL) указанной проблемы не решают.

В поисках решения нашел интересный способ избавления от моей проблемы, но не для РНР. Вот цитата:

Проблема связанная с ней, опять заключается в том, что установка соединения вполне вероятно может быть очень длительной операцией за счет плохих каналов передачи данных. Ведь этот процесс заключается в том, что по сети передаются несколько пакетов "туда и обратно" с просьбой открыть сокет, послать подтверждение и прочее... то есть, фактически, connect() опять же ничем принципиально не отличается от функций чтения и записи данных в сокеты. Тем не менее, за счет использования select() мы можем читать из сокета и писать в сокет по готовности, а окончания connect() вынуждены ждать
[Удален]
#1

А для чего собственно нужно вам это?


function fetch_remote_file($url) {
$user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9) Gecko/2008052906 Firefox/3.0';
@ini_set ( 'allow_url_fopen', '1' );
@ini_set ( 'default_socket_timeout', '5' );
@ini_set ( 'user_agent', $user_agent );
if (function_exists ( 'curl_init' )) {
if ($ch = curl_init ()) {
curl_setopt ( $ch, CURLOPT_URL, $url );
curl_setopt ( $ch, CURLOPT_HEADER, false );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt ( $ch, CURLOPT_CONNECTTIMEOUT, '5' );
curl_setopt ( $ch, CURLOPT_USERAGENT, $user_agent );
if ($data = curl_exec ( $ch )) {
curl_close ( $ch );
return $data;
}
}
}
return false;
}
К
На сайте с 03.02.2005
Offline
74
#2

KosoyRoman, спасибо за готовность помочь. Не могли бы Вы пояснить, в каком участке Вашего кода содержится ключ к решению моей проблемы? Стыдно признаться, но я увидел лишь стандартное использование библиотеки cURL, не решающее моей проблемы, как мне кажется.

KosoyRoman:
А для чего собственно нужно вам это?

Для чего нужно перевести fsockopen в неблокирующий режим? Чтобы дать возможность скрипту не останавливаться на время тайм-аута этой функции. Т.е. стандартная цель использования неблокирующего режима.

К
На сайте с 03.02.2005
Offline
74
#4
KosoyRoman:
вот же мануал

Хм... мне казалось, я корректно описал проблему, с которой столкнулся. Давайте, попробую объяснить с другого конца.

Проблема не в том, что я не могу организовать работу с fsockopen, stream_socket_client или cURL (с этим, как раз, все в порядке), а в том, что не получается у меня работать с сокетом в неблокирующем режиме с самого начала соединения. Эта же проблема хорошо описана по ссылке, которую я привел в первом посте. Т.е. мне надо, чтобы к моменту отправки первого бита в сторону удаленной машины (при установлении соединения) сокет уже находился в неблокирующем режиме.

Если же действовать стандартными методами, описанными в мануалах, то установить неблокирующий режим для сокета можно только после установления соединения с удаленной машиной. В подавляющем числе случаев этого достаточно. Я столкнулся с исключением - в отдельных случаях сам процесс установления соединения (когда сокет еще в блокирующем режиме) затягивается. Мне надо уйти от этого затягивания установив неблокирующий режим для функции fsockopen. Или для любой другой аналогичной, хоть для stream_socket_client, хоть для чего-то в cURL или в низкоуровневом интерфейсе сокетов.

[Удален]
#5

Смысл? не дать скрипту подвиснуть? Для этого и ставится таймаут у курла.

К
На сайте с 03.02.2005
Offline
74
#6
neolord:
Смысл?

Смысл есть.

У Вас есть решение?

neolord:
не дать скрипту подвиснуть? Для этого и ставится таймаут у курла.

Нет, конечно :) Неблокирующие сокеты немного для другого...

[Удален]
#7

Чтобы предложить решение мне сначала понять задачу. Просто "сделать неблокирующиеся сокеты" на основе функций пхп - не решается. Есть конечно функция

socket_set_nonblock -- Sets nonblocking mode for file descriptor fd

Description

bool socket_set_nonblock ( resource socket )

но не факт насчет там этого вашего первого бита

К
На сайте с 03.02.2005
Offline
74
#8
neolord:
Чтобы предложить решение мне сначала понять задачу.

Я, вроде, описал подробно. Допускаю, что криво. Можете уточняющие вопросы задать?

neolord:
Просто "сделать неблокирующиеся сокеты" на основе функций пхп - не решается.

Можно попросить пояснить? Почему не решается? В терминах РНР вроде как решается (за исключением самого начала, да и то, я не уверен, что это не мой косяк).

neolord:
Есть конечно функция socket_set_nonblock

У нее есть какие-нить принципиальные отличия от socket_set_blocking? За исключением того, что они из разных семейств.

N
На сайте с 06.05.2007
Offline
419
#9

есть специальная опция

curl_setopt ( $ch, CURLOPT_CONNECTTIMEOUT, '5' );

неужели не работает?

Кнопка вызова админа ()
К
На сайте с 03.02.2005
Offline
74
#10
netwind:
есть специальная опция
curl_setopt ( $ch, CURLOPT_CONNECTTIMEOUT, '5' );
неужели не работает?

Насколько я в курсе, это мы так просто тайм-аут выставляем. Без перехода в неблокирующий режим.

12 3

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий