sacred писал(а):
Спасибо за модуль.
Что-то у меня всё равно не получается.
<...>
Теперь ещё хуже. Входит в бесконечный цикл REPEAT UNTIL и всё. Такое ощущение, что вообще не может приконнектиться. При том, что ya.ru - живее всех живых... Запускал локальный web-сервер, пытался приконнектиться к localhost - та же песня.
Модуль точно рабочий?
Или я просто не умею его готовить?

Модуль точно рабочий. Просто нельзя делать ожидание в таком цикле. Если бы мы были в Delphi, вам следовало бы в REPEAT - UNTIL вставить вызов Application.ProcessMessages. В BlackBox нужно воспользоваться Services.Action.
Вот пример рабочего кода. Вместо цикла я разнес открытие соединения и проверку приема в разные команды, а поток сделал глобальной переменной.
Код:
MODULE PrivProbaTest;
IMPORT CommStreams, Log;
VAR
s : CommStreams.Stream;
PROCEDURE Test*;
VAR
res: INTEGER;
BEGIN (* ya.ru - 87.250.251.8 *)
CommStreams.NewStream("CommTCPAsync", "", "ya.ru:80", s, res)
END Test;
PROCEDURE Test2*;
VAR
read: INTEGER;
buff: ARRAY 100 OF BYTE;
BEGIN
IF s # NIL THEN
IF s.IsConnected() THEN
Log.String("connected");
s.ReadBytes(buff, 0, 100, read);
Log.Int(read)
ELSE
Log.String("closed");
END
ELSE
Log.String("Not connected");
END;
Log.Ln
END Test2;
END PrivProbaTest.
^Q PrivProbaTest.Test
^Q PrivProbaTest.Test2
А вот тот же пример, но с использованием Services.Action для автоматической проверки поступления новых данных раз в 2 секунды. Добавлен импорт Services, тип Action, метод Action.Do, процедура Stop и глобальная переменная action: Action. Доработана процедура Test, устанавливающая соединение.
Код:
MODULE PrivProbaTest;
IMPORT CommStreams, Log, Services;
TYPE
Action = POINTER TO RECORD (Services.Action) END;
VAR
s : CommStreams.Stream;
action: Action;
PROCEDURE Stop* ();
BEGIN
IF action # NIL THEN
Services.RemoveAction(action);
action := NIL
END
END Stop;
PROCEDURE Test*;
VAR
res: INTEGER;
BEGIN (* ya.ru - 87.250.251.8 *)
Stop;
CommStreams.NewStream("CommTCPAsync", "", "ya.ru:80", s, res);
IF res = 0 THEN
NEW(action);
Services.DoLater(action, Services.now) (* выполняем как можно скорее *)
END
END Test;
PROCEDURE Test2*;
VAR
read: INTEGER;
buff: ARRAY 100 OF BYTE;
BEGIN
IF s # NIL THEN
IF s.IsConnected() THEN
Log.String("connected");
s.ReadBytes(buff, 0, 100, read);
Log.Int(read)
ELSE
Log.String("closed");
END
ELSE
Log.String("Not connected");
END;
Log.Ln
END Test2;
PROCEDURE (act: Action) Do ();
BEGIN
Test2;
Services.DoLater(act, Services.Ticks() + 2 * Services.resolution) (* выполняем еще раз через 2 секунды *)
END Do;
END PrivProbaTest.
^Q PrivProbaTest.Test
^Q PrivProbaTest.Stop
Нижний предел периода вызова Services.Action.Do заложен в константе HostMenus.idlePeriod (по умолчанию = 50 мсек).
У меня модули называются PrivProbaTest, потому что я их поместил в подсистему Priv. Это имя подсистемы зарезервировано для "частного" использования.
PS: приведенные примеры проверены на ftp-сервисах (номер порта 21), но на http принять ничего не удалось, даже с того же ya.ru. Возможно, протокол http не предполагает стартового приветствия для подключившегося клиента. Этих тонкостей я не знаю, так как с http не работал.