Чтение с 2ух сокетов

Gashish

Новичок
Чтение с 2ух сокетов

Добрый день. Поискал по форуму, ничего похожего не нашел.

Я открываю два разных сокета и хотел бы отслеживать, когда один из них мне что-то отсылает. Т.е. отслеживать (например в цикле) какой из сокетов проявил активность и вызывать некоторую функцию, куда передаются данные из сокета, и продолжать отслеживать дальше.

Буду очень благодарен за коротенький код, если такое возможно.
 

Gashish

Новичок
Хочу оговориться, что я не выступаю "сервером" в данном случае, а наоборот, выступаю "клиентом"...

Т.е. у меня происходит следующее:
PHP:
$service_port = 5190;
$address = gethostbyname("hostname.ru");

$socket = socket_create (AF_INET, SOCK_STREAM, 0);
if($socket < 0)
{
  exit();
}

$result = socket_connect ($socket, $address, $service_port);
if ($result < 0)
{
  exit();
}

$start_time = time();
while (true) {
	if ((time()-$start_time)>30) {break;}
И вот тут надо что-то дописать
PHP:
}
Посмотрел я Help, там описваются сокеты, которые ожидают соединения, а не те, которые сами соединяются с сервером.
 

WP

^_^
> Хочу оговориться, что я не выступаю "сервером" в данном случае, а наоборот, выступаю "клиентом"...
А какая разница?
> $service_port = 5190;
Гы, подкинуть либу работы с аськой? Там некоторый гемор есть, но он решен.
 

_vampiro_

Новичок
WP

не пробывали выносить все мат. функции в отдельный класс там? Прикольная чтука, но функции не в тему :( неймспейс пересекается.

-~{}~ 23.06.06 11:36:

:) автозамена по файлу всё решила... ля-ля-ля.
 

Gashish

Новичок
Автор оригинала: WP
> Хочу оговориться, что я не выступаю "сервером" в данном случае, а наоборот, выступаю "клиентом"...
А какая разница?
> $service_port = 5190;
Гы, подкинуть либу работы с аськой? Там некоторый гемор есть, но он решен.
Не только аська работаета этом порту...
И как все-таки сделать чтение с двух сокетов одновременно?

Разница в том, что я не могу до конца как работает soket_select.
Что ему передавать в качестве массива? Набор из переменных типа $socket или типа $result в моем сучае?
 

WP

^_^
Не в качестве массива, а в качестве аргумента нужно передать массив, значениями которого являются Ресурсы от socket_create.
 

Gashish

Новичок
WP
Благодарю, буду пробовать

-~{}~ 26.06.06 11:23:

Вот попробовал, не получается =( Пришел опять за советом...
PHP:
<?php
error_reporting(E_ALL);
$service_port = 5190;
$address = gethostbyname("city1.timezero.ru");

$socket = socket_create (AF_INET, SOCK_STREAM, 0);
if($socket < 0)
{
  logMessage("socket_create() failed: The reason is: " . socket_strerror ($socket));
  logMessage("comClient goes down due to error.");
  exit();
}

$result = socket_connect ($socket, $address, $service_port);
if ($result < 0)
{
  logMessage("socket_connect() failed. The reason is: ($result) ".socket_strerror($result));
  logMessage("comClient goes down due to error.");
  exit();
}

logMessage("Connected to server $address:$service_port.");
logMessage("Waiting for data from server $address:$service_port.");

$start_time = time();
$mysock = array ($socket);
print_r($mysock);
$r = $mysock;
while (true) {
	if ((time()-$start_time)>60) {logMessage("Timeout");break;}
	if (false === ($num_changed_sockets = socket_select($r, $w = NULL, $e = NULL, 0))) {
    echo "socket_select() failed, reason: " . socket_strerror(socket_last_error()) . "\n";
	} else  if ($num_changed_sockets>0) {
		$data = socket_read($socket, 2048);
		if ($data === false) {
				logMessage ("No data");
       continue;
           }
    else {logMessage($data);}
			}
	}
?>
Скрипт висит и выпадает по таймауту, т.е. socket_select не находит изменения в сокете...
Если после коннекта сразу сделать
PHP:
$data = socket_read($socket, 2048);
, то данные будут...

Помогите, пожалуйста, разобраться...
 

fixxxer

К.О.
Партнер клуба
перед socket_connect вызови socket_set_nonblock
после socket_connect проверяй

PHP:
if (getenv('OSTYPE')=='FreeBSD')
  define('SOCKET_ERROR_IN_PROGRESS', 36);
else // Linux
  define('SOCKET_ERROR_IN_PROGRESS', 115);

if (SOCKET_ERROR_IN_PROGRESS != socket_last_error($socket_resource) ) {
 // ошибка
} else {
  socket_clear_error($socket_resource);
 // ok, делаем socket_select
}
 

Gashish

Новичок
fixxxer
В этом месте
PHP:
if (SOCKET_ERROR_IN_PROGRESS != socket_last_error($socket_resource) ) {    // ошибка   }
пишет:
Ошибка: Operation now in progress
 

WP

^_^
Я ж говорю, там пришлось целый workaround сооружать, по совокупности значений разных.
 

Gashish

Новичок
fixxxer

Чего-то я не понял.
Там как раз выполняется ветка условия
if (SOCKET_ERROR_IN_PROGRESS != socket_last_error($socket_resource) ) { // ошибка }
и он не идет в ветку, где по твоим словам толжен быть socket_select

WP
Повторюсь, аська тут совершенно не причем...
 

fixxxer

К.О.
Партнер клуба
ну значит в твоей ОС другой номер этой ошибки (точнее говоря, псевдоошибки). поправь там. (какая ось, кстати)?
 

Gashish

Новичок
fixxxer

Как ни странно 36 =)

Кстати, когда вызываю
PHP:
if (!socket_set_nonblock($socket)) {
   echo socket_strerror(socket_last_error());
}
перед socket_connect, получаю:

Warning: socket_connect() [function.socket-connect]: unable to connect [36]: Operation now in progress in /www/tzclub/www/htdocs/tryagain.php on line 46

Без него, естественно, ошибки нету...

-~{}~ 26.06.06 23:43:

Господа знатоки, все оказалось банально и решение лежало на поверхности. Оказывается socket_select() начинал работать дотого, как в сокете появлялись данные, соответственно он возвращал 0.

Решение - выставляем параметр int tv_sec равным 1 секунде и все замечательно работает:
PHP:
socket_select($r, $w = NULL, $e = NULL, 1)
Жалко, только, что решение нашлось на другом форуме
 
Сверху