OberonCore
https://forum.oberoncore.ru/

Работа с сетью
https://forum.oberoncore.ru/viewtopic.php?f=23&t=382
Страница 1 из 1

Автор:  sacred [ Вторник, 13 Февраль, 2007 20:04 ]
Заголовок сообщения:  Работа с сетью

Никто не встречал ничего готового по работе с сетью?
Что-то я поискал - не нашёл. Может плохо искал? Ткните носом, плииз!

Автор:  zh [ Вторник, 13 Февраль, 2007 21:22 ]
Заголовок сообщения: 

Смотрим подсистему Comm
CommTCP
Драйвер для CommStreams.
Он реализует каналы TCP/IP, используя механизм сокетов операционной системы.
Примеры
CommObxStreamsClient
CommObxStreamsServer

Автор:  Александр Ильин [ Среда, 14 Февраль, 2007 11:41 ]
Заголовок сообщения:  Re: Работа с сетью

sacred писал(а):
Никто не встречал ничего готового по работе с сетью?
Что-то я поискал - не нашёл. Может плохо искал? Ткните носом, плииз!

CommTCP, как было верно замечено выше. Но этот модуль обладает одним неприятным недостатком: асинхронность сокетов работает только после установки соединения. Другими словами, если удаленный сервер не доступен, BlackBox будет подвисать на то время, пока пытается связаться. Поэтому однозначный маст хэв здесь:
http://espc22.murdoch.edu.au/~stewart/blackbox/
Там есть модуль CommTCPAsync, при использовании которого в качестве драйвера указанного зависания нет.

Автор:  sacred [ Четверг, 15 Февраль, 2007 11:48 ]
Заголовок сообщения:  Re: Работа с сетью

Александр Ильин писал(а):
Поэтому однозначный маст хэв здесь:
http://espc22.murdoch.edu.au/~stewart/blackbox/
Там есть модуль CommTCPAsync, при использовании которого в качестве драйвера указанного зависания нет.

Спасибо большое, буду разбираться. А, кстати, чего-нибудь ещё более высокоуровнего нет? Типа реализаций каких-нибудь HTTP, FTP - протоколов и т.д.?

P.S. Проверил. Ссылочка не работает. Нет ли скачанного модуля?

Автор:  sacred [ Четверг, 22 Февраль, 2007 00:33 ]
Заголовок сообщения:  Re: Работа с сетью

Как уже говорил, ссылка не работает. Киньте кто-нибудь в меня асинхронным модулем, пожалуйста!

Между тем, попробовал использовать стандартный модуль. Вот что вышло:

Код:

MODULE ProbaTest;
IMPORT CommStreams, Log;

PROCEDURE Test*;
VAR
   s : CommStreams.Stream;
   res : INTEGER;
BEGIN (*  ya.ru - 87.250.251.8 *)
   CommStreams.NewStream("CommTCP", "", "ya.ru", s, res);
   CASE res OF
   CommStreams.done:Log.String("done")
   |CommStreams.noSuchProtocol:Log.String("noSuchProtocol")
   |CommStreams.networkDown:Log.String("networkDown")
   |CommStreams.invalidLocalAdr:Log.String("invalidLocalAdr")
   |CommStreams.localAdrInUse:Log.String("localAdrInUse")
   |CommStreams.invalidRemoteAdr:Log.String("invalidRemoteAdr")
   |CommStreams.remoteAdrInUse:Log.String("remoteAdrInUse")
   END;
   IF s.IsConnected() THEN
      Log.String("connected");
   ELSE
      Log.String("Not connected");
   END
END Test;

END ProbaTest.


Пишет : "done", а потом "Not connected". Соответственно, уже процедура ReadBytes - тоже не работает. В чём ошибка, никто не знает?

Автор:  Александр Ильин [ Четверг, 22 Февраль, 2007 02:16 ]
Заголовок сообщения: 

Действительно, ссылка не работает. Выложил сюда.

По поводу ProbaTest: надо в строке адреса указать порт, к которому вы присоединяетесь. Например "ya.ru:80". Число десятичное. По умолчанию считается = 0, поэтому и не работает.

Автор:  sacred [ Воскресенье, 25 Февраль, 2007 00:55 ]
Заголовок сообщения: 

Спасибо за модуль.
Что-то у меня всё равно не получается.
Код:
MODULE ProbaTest;
IMPORT CommStreams, Log, CommTCPAsync;

PROCEDURE Test*;
VAR
   s : CommStreams.Stream;
   as : CommTCPAsync.Stream;
   res : INTEGER;
BEGIN (*  ya.ru - 87.250.251.8 *)
   CommStreams.NewStream("CommTCPAsync", "", "ya.ru:80", s, res);
   IF s.IsConnected() THEN
      as := s(CommTCPAsync.Stream);
      REPEAT UNTIL as.HasConnected();
      Log.String("connected");
   ELSE
      Log.String("Not connected");
   END
END Test;

END ProbaTest.

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

Автор:  sacred [ Воскресенье, 25 Февраль, 2007 01:02 ]
Заголовок сообщения: 

И дубль два. Попытка прочитать что-либо стандартным модулем:
Код:
MODULE ProbaTest;
IMPORT CommStreams, Log;

PROCEDURE Test*;
VAR
   s : CommStreams.Stream;
   res, read : INTEGER;
   buff : ARRAY 100 OF BYTE;
BEGIN (*  ya.ru - 87.250.251.8 *)
   CommStreams.NewStream("CommTCP", "", "ya.ru:80", s, res);
   IF s.IsConnected() THEN
      Log.String("connected");
      s.ReadBytes(buff, 0, 100, read);
      Log.Int(read);
   ELSE
      Log.String("Not connected");
   END;

   IF s.IsConnected() THEN
      Log.String("closed");
   END;

END Test;

END ProbaTest.

Пишет соответственно: done 0 closed
Блин! 3 функции, а вызвать правильно не могу. Что-то здесь не так... Вопрос: что?

Автор:  Александр Ильин [ Воскресенье, 25 Февраль, 2007 10:26 ]
Заголовок сообщения: 

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 не работал.

Автор:  Александр Ильин [ Воскресенье, 25 Февраль, 2007 10:29 ]
Заголовок сообщения: 

sacred писал(а):
И дубль два. Попытка прочитать что-либо стандартным модулем:
<...>
Пишет соответственно: done 0 closed
Блин! 3 функции, а вызвать правильно не могу. Что-то здесь не так... Вопрос: что?

Вы все правильно вызываете. Проблема в том, что так сразу ничего принять невозможно, нужно подождать. К тому же, надо уточнить, должен ли вообще http сервер что-то передавать "просто так", без запроса.

Автор:  Alexander Shiryaev [ Вторник, 27 Февраль, 2007 18:11 ]
Заголовок сообщения: 

не должен

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/