СОКЕТЫ
Сокет - инструмент позволяющий организовать сетевое взаимодействие приложений типа "точка-точка". В ABL существует два типа сокетов: Server Socket и Client Socket. Server Socket выполняет роль коммутатора, а Client Socket - роль оконечного оборудования связи.
SERVER SOCKET
SERVER SOCKET - Слушает TCP/IP порт обрабатывая клиентские подключения.
CREATE SERVER-SOCKET handle [NO-ERROR].
где, handle - переменная HANDLE типа, в которою будет записан handle создаваемого сервер-сокета.
АТРИБУТЫ:
Атрибут | Тип аргумента | Чтение/Запись | Описание |
HANDLE | HANDLE | чтение | handle сервер-сокета |
INSTANTIATING-PROCEDURE | HANDLE | чтение | Возвращает handle процедуры в которой был объявлен сервер сокет |
NAME | CHARACTER | чтение/запись | имя сервер сокета |
NEXT-SIBLING | HANDLE | чтение | Возвращает последующий handle сервер сокета из числа сокетов текущей сессии. По достижению конца списка возвращает неизвестное значение (?). |
PREV-SIBLING | HANDLE | чтение | Возвращает предыдущий handle сервер сокета из числа сокетов текущей сессии. По достижению начала списка возвращает неизвестное значение (?). |
PRIVATE-DATA | CHARACTER | чтение/запись | Свободный атрибут |
SENSITIVE | LOGICAL | чтение/запись | Отражает возможность сервер сокета реагировать на события. По умолчание имеет значение TRUE. |
TYPE | CHARACTER | чтение | Возвращает значение SERVER-SOCKET |
МЕТОДЫ:
ENABLE-CONNECTIONS(connection-parms) - осуществляет запуск сервера с указанными параметрами. Результатом является логическое значение, отражающее успешность или не успешность запуска сервера.
- connection-parms - Строка параметров подключения:
Параметр | Описание |
-S socket-port | Номер порта сервера |
-pf filename | filename - файл с параметрами |
-qsize backlog | Максимальное число запросов находящихся в очереди ожидания на обработку сервером |
-ssl | SSL-соединение |
-keyalias aliasname | |
-keyaliaspasswd encpwd | |
-nosessioncache | Отключение кэширования SSL сессии |
-sessiontimeout [seconds] | Время ожидания сервера в секундах до сброса SSL клиента, по умолчанию 180 секунд. |
DISABLE-CONNECTIONS() - прекращает прием запросов сервером. Возвращает логическое значение TRUE в случае успешной остановки сервера.
SET-CONNECT-PROCEDURE(event-internal-procedure [,procedure-context]) - определяет процедуру обработки клиентских запросов, т.е. процедуру вызываемую по событию подключения очередного клиента. Данная процедура должна обладать одним входным параметром типа handle. При вызове метода данной процедуре будет передан handle сокета.
- event-internal-procedure - текстовое значение имени процедуры.
- procedure-context - параметры передаваемые процедуре.
SOCKET
SOCKET - осуществляет непосредственный обмен сообщениями с подключившимся клиентом.
АТРИБУТЫ:
Атрибут | Тип аргумента | Чтение/Запись | Описание |
BYTES-READ | INTEGER | чтение | Возвращает количество байт полученных в ходе последнего выполнения метода READ(). Если последнее выполнение метода READ() завершилось с ошибкой, то возвращается 0. |
BYTES-WRITTEN | INTEGER | чтение | Возвращает количество байт полученных в ходе последнего выполнения метода WRITE(). Если последнее выполнение метода WRITE() завершилось с ошибкой, то возвращается 0. |
HANDLE | HANDLE | чтение | handle сокета |
INSTANTIATING-PROCEDURE | HANDLE | чтение | Возвращает handle процедуры в которой был объявлен сокет |
LOCAL-HOST | CHARACTER | чтение | IP-адрес сокета. Если подключение не установлено, возвращает неизвестное значение (?). |
LOCAL-PORT | INTEGER | чтение | Порт сокета. Если подключение не установлено, возвращает неизвестное значение (?). |
NAME | CHARACTER | чтение/запись | имя сервер сокета |
NEXT-SIBLING | HANDLE | чтение | Возвращает последующий handle сокета из числа сокетов текущей сессии. По достижению конца списка возвращает неизвестное значение (?). |
PREV-SIBLING | HANDLE | чтение | Возвращает предыдущий handle сервер сокета из числа сокетов текущей сессии. По достижению начала списка возвращает неизвестное значение (?). |
PRIVATE-DATA | CHARACTER | чтение/запись | Свободный атрибут |
REMOTE-HOST | CHARACTER | чтение | IP-адрес подключенного клиента. Если подключение клиента не установлено, возвращает неизвестное значение (?). |
REMOTE-PORT | INTEGER | чтение | Порт подключенного клиента. Если подключение клиента не установлено, возвращает неизвестное значение (?). |
SENSITIVE | LOGICAL | чтение/запись | Отражает возможность сокета реагировать на события. По умолчание имеет значение TRUE. |
SSL-SERVER-NAME | CHARACTER | чтение | Имя SSL сервера. Если соединение не использует SSL возвращает неизвестное значение (?) |
TYPE | CHARACTER | чтение | Возвращает значение SERVER-SOCKET |
МЕТОДЫ:
CONNECT([connect-parms]) - устанавливает соединение. Метод возвращает значение типа LOGICAL отражающее успешность (TRUE) или не успешность (FALSE) установки соединения.
connect-parms - параметры соединения:
Параметр | Описание |
-H socket-address | Имя хоста или IP-адрес сокета |
-S socket-port | Номер порта сокета |
-pf filename | filename - файл с параметрами |
-ssl | Указывается, если сервер-сокет использует SSL |
-nosessionreuse | |
-nohostverify |
CONNECTED( ) - метод возвращает логическое значение состояния подключения.
DISCONNECT( ) - осуществляет отключение сокета. Метод возвращает логическое значение отражающее успешность выполнения отключения.
SET-SOCKET-OPTION(name, arguments) - устанавливает значение параметров (опций) сокета:
Параметр | Описание |
TCP-NODELAY | Логическое значение ("TRUE"/"FALSE") включающее/отключающее применение Алгоритма Нейглала |
SO-LINGER | При вызове метода DISCONNECT() полное освобождение сокета происходит не сразу. Сокет перестает быть доступным, но продолжает удерживаться системой еще некоторое время, для дополучения из сети всех переданных ему данных "блуждающих" в сети. Время между вызовом DISCONNECT() и полным освобождением сокета рассчитывается исходя из максимального времени существования пакета в сети. SO-LINGER позволяет управлять интервалом времени между вызова метода DISCONNECT() и полным закрытием сокета. Значение данного параметра представляет собой логическое значение, отражающее применение данного параметра, и значение времени ожидания, указанные через разделитель запятая. |
SO-KEEPALIVE | Эта опция указывает, должен ли TCP-протокол периодически передавать сообщение keepalive (подтверждение доступности) на соединенный сокет. Если адресат будет не в состоянии ответить на это сообщение, соединение считается разорванным. Возможное значение - "TRUE"/"FALSE". |
SO-REUSEADDR | Возможное значение - "TRUE"/"FALSE". |
SO-RCVBUF SO-SNDBUF |
Определяют размеры входных и выходных буферов сокета |
SO-RCVTIMEO | Определяет значение тайм-аута сокета, заданного в секундах |
GET-SOCKET-OPTION(name) - метод возвращает значение указанного параметра name cокета.
SET-READ-RESPONSE-PROCEDURE(procedure, procedure-context) - определяет процедуру обрабатывающую событие запрос-ответ.
- procedure - имя процедуры;
- procedure-context - handle процедуры содержащей procedure . По умолчанию THIS-PROCEDURE.
GET-BYTES-AVAILABLE( ) Метод возвращает число байт доступных для чтения с сокета, INTEGER типа.
READ(buffer, position, bytes-to-read [, mode]) Чтение полученных сокетом данных. Метод возвращает логическое значение (тип LOGICAL), отражающее успешность выполнения чтения данных.
- buffer - MEMPTR значение, определяющее, где должны быть размещены полученные данные;
- position - порядковый номер байта (значение должно быть больше нуля), начиная с которого будет осуществляться запись в buffer, тип INTEGER;
- bytes-to-read - количество байт которое будет прочитано из сокета, тип INTEGER;
- mode - определяет режим чтения данных, тип INTEGER.
WRITE(buffer, position, bytes-to-write)
- buffer - MEMPTR значение, определяющее буфер данных для записи в сокет;
- position - целочисленное значение типа INTEGER большее 0, указывающее позицию стартового байта в буфере buffer, данные которого должны быть записаны в сокет;
- bytes-to-write - количество байт данных, которые должны быть записаны из буфера в сокет.
ПРИМЕР РАБОТЫ С SOCKET
SERVER SOCKET
DEF VAR vOk AS LOGICAL NO-UNDO. /* успешность запуска сервера */
/* Создание server socket */
CREATE SERVER-SOCKET hServSocket NO-ERROR.
/* Запуск server socket */
DEF VAR aOk AS LOGICAL NO-UNDO.
vOk = hServSocket:ENABLE-CONNECTIONS("-S 4080").
IF NOT vOk THEN RETURN.
/* Определение процедуры метода CONNECT */
hServSocket:SET-CONNECT-PROCEDURE("connect-proc").
DO ON STOP UNDO, LEAVE:
WAIT-FOR CLOSE OF THIS-PROCEDURE.
END.
hServerSocket:DISABLE-CONNECTIONS().
DELETE OBJECT hServerSocket.
/* Процедура метода CONNECT */
PROCEDURE connect-proc:
DEF INPUT PARAMETER hSocket AS HANDLE. /* socket handle */
IF VALID-HANDLE(hSocket) THEN
DO:
hSocket:SET-READ-RESPONSE-PROCEDURE("read-handler", THIS-PROCEDURE).
END.
END PROCEDURE.
/* Процедура обработки запросов */
PROCEDURE read-handler:
DEF VAR mBuffer AS MEMPTR NO-UNDO.
DEF VAR vLenReq AS INT64 NO-UNDO.
DEF VAR vLenResp AS INT64 NO-UNDO.
DEF VAR vHost AS CHAR NO-UNDO. /* с какого хоста запрос */
DEF VAR vRequest AS LONGCHAR NO-UNDO. /* Запрос */
DEF VAR vResponce AS LONGCHAR NO-UNDO. /* Ответ */
/********************** ЗАПРОС ************************/
vHost = hSocket:REMOTE-HOST. /* с какого хоста запрос */
vLenReq = hSocket:GET-BYTES-AVAILABLE(). /* размер входящего запроса */
IF vLenReq > 0 THEN
DO:
/* читаем запрос в буфер */
SET-SIZE(mBuffer) = vLenReq.
hSocket:READ(mBuffer, 1, vLenReq, 1).
COPY-LOB mBuffer FOR vLenReq TO vRequest.
/* освобождаем буфер */
SET-SIZE(mBuffer) = 0.
/************************* ОТВЕТ **********************/
vResponce = "Привет " + vRequest.
vLenResp = LENGTH(vResponce).
IF vLenResp > 0 THEN
DO:
SET-SIZE(mBuffer) = vLenResp.
COPY-LOB vResponce FOR vLenResp TO mBuffer.
/* непосредственно ответ */
hSocket:WRITE(mBuffer,1,vLenResp)).
/* освобождаем буфера */
SET-SIZE(mBuffer) = 0.
END.
END.
hSocket:DISCONNECT().
DELETE OBJECT hSocket.
END PROCEDURE.