Программирование >>  Oracle 

1 ... 455 456 457 [ 458 ] 459 460 461 ... 469


Пакет UTL TCP

В версии Oracle 8.1.6 появился пакет UTL TCP. Он позволяет, работая в PL/SQL, устанавливать через сетевой сокет TCP/IP-соединение с любым сервером. Если известен протокол сервера, можно общаться с ним из PL/SQL. Например, зная протокол HTTP (Hyper Text Transfer Protocol - протокол передачи гипертекста), можно с помощью пакета UTL TCP выполнить следующее:

test jsock@DEV816> DECLARE

c utl tcp.connection; - TCP/IP-подключение

к Web-оерверу

n number;

buffer varchar2(255);

BEGIN

c :=utl tcp.open connection(proxy-server,

80);

n :=utl tcp.write line(c, GEThttp: www.wrox.com/HTTP/1.0) ;

n :=utl tcp.write line(c);

BEGIN

LOOP

n:=utl tcp.read text(c, buffer, 255);

dbms output.put line(buffer);

END LOOP;

EXCEPTION

WHEN utl tcp.end of input THEN

NULL; - конец входных данных

end;

utl tcp.close connection(c);

END;

HTTP/1.1 2 00 OK



1798 Приложение А

Date: Tue, 30 Jan 2001 11:33:50 GMT Server: Apache/1.3.9 (Unix) mod perl/1.21 ApacheJServ/1.1 Content-Type: text/html

<head>

<title>Oracle Corporation</title>

Этот PL/SQL-блок позволил мне подключиться к серверу, в данном случае - промежуточному, с именем proxy-server. Через брандмауэр я попал в Intemet. Это произошло в строке 6. Затем я запросил Web-страницу, в строках 7 и 8. В строках с 10 по 13 мы получаем содержимое этой Web-страницы, включая все существенные заголовки HTTP (которые, кстати, стандартный пакет UTL HTTP не позволяет получить). Затем пакет UTL TCP возбуждает исключительную ситуацию UTL TCP.END OF INPUT, страница получена, и мы выходим из цикла. После этого мы отключаемся.

Этот простой пример демонстрирует большую часть функциональных возможностей пакета UTL TCP. Мы не вызываем функции типа AVAILABLE, информирующие о том, есть ли данные для получения. Мы не вызываем процедуру FLUSH, передающую все результаты, находящихся в буфере (буферизация не используется, поэтому такой вызов не нужен). Мы не использовали все возможные варианты вызовов READ, WRITE и GET для обмена данными через сокет, но представленный пример достаточно полно демонстрирует особенности использования пакета UTL TCP.

Меня не всегда устраивает скорость работы подобных фрагментов кода. По моему опыту, пакет UTL TCP, хотя и работает, но в данной версии (Oracle 8i) имеет недостаточную производительность. В версии 8.1.7.1 проблема низкой производительности решена (речь идет об исправлении ошибки #1570972).

Насколько же медленно работает подобный код? Представленный выше код для выборки документа размером 16 Кбайт требует от четырех до десяти секунд, в зависимости от платформы. Это, конечно, - медленно, особенно по сравнению с тем, что соответствующая функция пакета UTL HTTP позволяет загрузить такой же документ за доли секунды. К сожалению, пакет UTL HTTP не позволяет работать с ключиками, заголовками HTTP, двоичными данными, выполнять простейшую аутентификацию и т.п., поэтому альтернативные варианты часто оказываются полезными. Я думаю, можно сделать лучше. Для этого мы реализуем собственный пакет UTL TCP. При этом будем использовать объектные типы, работа с которыми рассматривалась в главе 20. Мы реализуем в PL/SQL тип SocketType, частично на языке Java. В разделе, посвященном пакету UTL HP, мы использовали этот же тип, SocketType, для создания более удобного пакета UTL HTTP. Поскольку интерфейс создаваемого типа построен по аналогии с возможностями пакета UTL TCP, когда в версии Oracle9i появится встроенная, более эффективная реализация пакета UTL TCP, мы легко сможем изменить тело типа, используя обращения к пакету UTL TCP, и отказаться от нынешней реализации на базе Java.

Тип SocketType

Объектный тип SocketType будет иметь следующую спецификацию:



Пакет UTL TCP

1799

tkyte@TKYTE816> create or replace type SocketType

10 11 12 13 14 15 16 17 18 19 20 21 22

object

- Приватные данные вместо передачи контекста

- каждой процедуре, как при использовании

- пакета UTL FILE. g sock number,

- Функция, возвращающая CRLF. Для удобства, static function crlf return varchar2,

- Процедуры для передачи данных через сокет. member procedure send(p data in varchar2) , member procedure send(p data in clob) ,

member procedure send raw(p data in raw) , member procedure send raw(p data in blob) ,

- Функции для получения данных через сокет. При закрытии сокета

- (поучении eof) они возвращают Null. Будут ждать данных,

- блокируя работу. Если это нежелательно, используйте

- представленную ниже функцию РЕЕК, чтобы узнать, есть ли

-> данные для чтения.

25 26

-> по

32 33 34

38 39 40 41 42

member function recv return varchar2, member function recv raw return raw,

- Служебная функция. Читает данные, пока не обнаружит CRLF.

- Может удалять CRLF, при желании пользователя (или не удалять, умолчанию).

member function getline(p remove crlf in boolean default FALSE) return varchar2,

- Процедуры для подключения к хосту и отключения от него.

- Важно не забывать отключаться, а то произойдет утечка

- ресурсов и, рано или поздно, подключиться не удастся, member procedure initiate connection(p hostname in varchar2,

p portno in number) ,

member procedure close connection.

- Функция, информующая

- можно прочитать.

member function peek return number

о том, сколько байтов (как минум)

Type created.

Функциональные возможности этого типа во многом подобны предлагаемым пакетом UTL TCP, да и интерфейс практически тот же. При желании тип можно реализовать на базе средств этого пакета. Мы, однако, собираемся реализовать его на базе другого пакета - SIMPLE TCP CLIENT. Это обычный пакет PL/SQL, на базе которого будет создан тип SocketType. Вот спецификация нашей версии пакета UTL TCP:



1 ... 455 456 457 [ 458 ] 459 460 461 ... 469

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика