Fakeman
Новичок
Не работает скрипт с неблокирующим сокетом
Есть вот такой кусок код для работы с неблокирующими сокетами, который по какой-от причине не работает...
Кто-нибудь может подсказать, где моя ошибка? Я грешу на socket_write, потому как в хелпе написано, что записано может быть и меньше байт, чем указано в самой команде в зависимости от некоторых факторов... но что конкретно я делаю не так, не могу понять...
Протокол работы скрипта:
[09:36:36] socket 0 created
[09:36:36] socket set non-blocking
[09:36:36] socket option set successfully
[09:36:36] host is resolved to 127.0.0.1
[09:36:36] socket is connecting... (10035) Операция на незаблокированном сокете не может быть завершена немедленно.
[09:36:36] headers
GET / HTTP/1.0
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Host: www2.jrc.local
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Referer: http://www2.jrc.local
Connection: Close
[09:36:36] socket selection started
[09:36:36] 1 changed state
[09:36:36] sockets for read = 0
[09:36:36] sockets for write = 1
[09:36:36] socket 0 is written 282 bytes
[09:36:36] 1 changed state
[09:36:36] sockets for read = 0
[09:36:36] sockets for write = 1
[09:36:36] socket 0 is written 282 bytes
... и так ОЧЕНЬ долго... получается, что я никак не могу получить written_bytes = 0, что скажет мне об окончании отсылки...
Есть вот такой кусок код для работы с неблокирующими сокетами, который по какой-от причине не работает...
Кто-нибудь может подсказать, где моя ошибка? Я грешу на socket_write, потому как в хелпе написано, что записано может быть и меньше байт, чем указано в самой команде в зависимости от некоторых факторов... но что конкретно я делаю не так, не могу понять...
PHP:
// метод connect (приведен в сокращении)
$sock = socket_create()
socket_set_option( $sock,...)
socket_connect( $sock,..);
$this->sockets[$id]["resource"] = $sock;
$this->sockets[$id]["connected"] = false;
// метод run
foreach ( $this->sockets as $sockets ) {
$read_sockets[] = $sockets["resource"];
$write_sockets[] = $sockets["resource"];
}
$num_changed_sockets = socket_select ( $read_sockets, $write_sockets, $except = null, 0 );
if ( $num_changed_sockets === false ) {
$this->_error ( null, "socket_select() failed !" );
$this->_logger->write ( "ошибка select_socket " . $this->_print_error() );
break;
} elseif ( $num_changed_sockets > 0 ) {
$this->_logger->write ( $num_changed_sockets . " changed state" );
$this->_logger->write ( "sockets for read = " . count ( $read_sockets ) );
$this->_logger->write ( "sockets for write = " . count ( $write_sockets ) );
// пишем в сокет для записи
foreach ( $write_sockets as $wsid => $ws ) {
if ( !$this->sockets[$wsid]["connected"] ) {
$errno = @socket_get_option ( $ws, SOL_SOCKET, SO_ERROR );
if ( $errno != 0 ) {
$this->sockets[$wsid]["connected"] = "timeout";
$this->_logger->write ( "socket " . $wsid . " is timeouted " . $this->_print_error() );
$this->_disconnect ( $wsid );
}
}
// пишем, если еще не писали
if ( !$this->sockets[$wsid]["written"] ) {
$write_data = $this->sockets[$wsid]["request"];
if ( ( $written_bytes = @socket_write ( $ws, $write_data, strlen ( $write_data ) ) ) === false ) {
$this->_logger->write ( "socket_write() failed " . $this->_print_error() );
$this->_disconnect ( $wsid );
} elseif ( $written_bytes == 0 ) { // по-идее все отослано
$this->sockets[$wsid]["written"] = true;
$this->_logger->write ( "socket " . $wsid . " is written" );
} else {
$this->_logger->write ( "socket " . $wsid . " is written " . $written_bytes . " bytes" );
}
}
}
// читаем из сокета
foreach ( $read_sockets as $rsid => $rs ) {
if ( ( $read_string = socket_read ( $rs, $this->rcvbuf ) ) === false ) {
$this->_logger->write ( "socket_read() failed " . $this->_print_error() );
$this->_disconnect ( $rsid );
} elseif ( strlen ( $read_string ) == 0 ) {
$this->results[$this->sockets[$rsid]["url"]] = $this->sockets[$rsid]["response"];
$this->_logger->write ( "socket " . $rsid . " is stopped talking " . $this->_print_error() );
$this->_disconnect ( $rsid );
$this->_logger->write ( "remain sockets " . count ( $this->sockets ) );
} else {
$this->sockets[$rsid]["response"] .= $read_string;
$this->_logger->write ( "socket " . $rsid . " reading - " . $this->sockets[$rsid]["response"] );
}
}
}
[09:36:36] socket 0 created
[09:36:36] socket set non-blocking
[09:36:36] socket option set successfully
[09:36:36] host is resolved to 127.0.0.1
[09:36:36] socket is connecting... (10035) Операция на незаблокированном сокете не может быть завершена немедленно.
[09:36:36] headers
GET / HTTP/1.0
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Host: www2.jrc.local
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Referer: http://www2.jrc.local
Connection: Close
[09:36:36] socket selection started
[09:36:36] 1 changed state
[09:36:36] sockets for read = 0
[09:36:36] sockets for write = 1
[09:36:36] socket 0 is written 282 bytes
[09:36:36] 1 changed state
[09:36:36] sockets for read = 0
[09:36:36] sockets for write = 1
[09:36:36] socket 0 is written 282 bytes
... и так ОЧЕНЬ долго... получается, что я никак не могу получить written_bytes = 0, что скажет мне об окончании отсылки...
... Упростил код... заодно увидел как минимум одну ошибку... здесь