Difference between revisions of "USR1 протокол"
m (1 revision imported) |
|
(No difference)
| |
Latest revision as of 07:54, 7 February 2021
USR1 это простой внутрисистемный протокол, позволяющий осуществлять обмен файлами и другой информацией. Удобство его использования заключается в том, что протокол встроен в общесистемных набор протоколов общения и не требует написания части приветствия, в которую также входит обмен файлами, что делает его простым в описании и удобным для использования для несложных программ обмена.
Для создания сервера, работающего по данному протоколу, можно добавить дополнительный раздел текста в ini-файл клиента (консольного или визуального), либо использовать функцию ListenUSR1.
//Раздел инициализации USR1 сервера в ini-файле клиента. [TCPServer] Ports="13522" Password="xxxxxxxxxxx"
Протокол выделяет понятие команда. Пакет с командой занимает 4 байта и содержит заранее определенное слово и 4 латинских букв. Для обмена командами можно использовать функции SendCmd и ReceiveCmd. В протоколе можно использовать шифрование (как и для любого TCP соединения), однако, шифрование можно включить только после инициации приветствия, что ограничивает использование протокола для обмена конфиденциальной информацией.
Последовательность действий при обмене по USR1 протоколу:
- Клиентская часть вызывает функцию ConnectUSR1 и получает TCP объект, с помощью которого ведется обмен.
- Клиентская часть использует конструкцию .SendCmd("USR1"), для инициализации USR1 протокола после соединения с сервером.
- Клиентская часть получает ответ с помощью функции .ReceiveCmd(). В ответ сервер может:
- Разорвать соединение (USR1 не поддерживается)
- Отдать команду "BUSY" (сервер занят обслуживанием другого клиента или максимального количества клиентов)
- Отдать команду "OK " (сервер готов к обслуживанию по USR1 протоколу)
- Клиентская часть использует конструкцию .SendStr(<Строка>), для пересылки любой начальной информации для сервера.
- При необходимости отсылки группы файлов вместе с начальной информацией, клиент для каждого из файлов последовательно отсылает команду "RECV" (.SendCmd("RECV")) и отсылает файл с помощью .SendFile.
- После того, как последний файл будет отослан (либо отсылка файлов не производилась вообще), клиент отсылает команду "FNSH".
- В сервеной части запускается выполнение события OnUsr1Connection, которое на основании текущего состояния системы должно ответить командой "OK " (обмен инициирован), "BUSY" (север уже занят обслуживанием одного или максимального количества клиентов) или разорвать соединение.
- Клиентская часть получает ответ с помощью функции .ReceiveCmd() и, руководствуясь им, продолжает или заканчивает обмен.
- Дальнейший протокол обмена задается программно.
Примеры
Исходный код с примерами серверной и клиентской частей:
//Исходный код примера клиентской части
Function ПровестиОбмен()
Сокет:=IPConnection.ConnectUSR1("127.0.0.1:13777");//Инициация соединения
If not Сокет.isConnected() Then
Message("Сервер не отвечает","!");
Exit 0;
EndIf;
СтрОшибка:="";
Try
СтрОшибка:="Сервер не принял режим USR1 (1)!";
Сокет.SendCmd("USR1");
Комм:=Сокет.ReceiveCmd();
If Комм="BUSY" Then
Message("Сервер занят!","!");
Exit 0;
EndIf;
If Комм<>"OK " Then
Message("Сервер не принял режим USR1 (2)!","!");
Exit 0;
EndIf;
СтрОшибка:="Ошибка при обмене!";
Сокет.SendStr("Hello, this is client!");
//Отсылка текстового файла C:\file.txt
Сокет.SendCmd("RECV");
Сокет.SendFile("C:\file.txt",1);
//Окончание обмена файлами
Сокет.SendCmd("FNSH");
Комм:=Сокет.ReceiveCmd();
If Комм<>"OK " Then
Exit 0;
EndIf;
Стр:="Любая информация для обмена";
Сокет.SendStr(Стр,1);
Сокет.ReceiveStr(Стр,1);
Message("Сервер прислал информацию: "+Стр);
//Далее следует обмен любой другой информацией
Except
If СтрОшибка<>"" Then
Message(СтрОшибка,"!");
Else
Message(PopError(),"!");
EndIf;
Exit 0;
EndTry
Exit 1;
EndFunction
//Исходный код примера серверной части
Function OnUsr1Connection(Сокет,Параметр,FList)
Try
Message("Клиент при соединении использовал параметр: "+Параметр);
If ThreadCount()>1 Then
//Данный сервер не будет принимать новых клиентов, пока предыдущий запрос не обработан в полной мере
Сокет.SendCmd("BUSY");
Exit;
EndIf;
Сокет.SendCmd("OK ");
For i:=1 To FList.Size() Do
Message("Клиент прислал файл: "+FList.Get(i));
Message(" Размер файла: "+File.GetFileSize(FList.Get(i)));
EndDo;
Стр:=Сокет.ReceiveStr(Стр,1);
Message("Клиент прислал информацию: "+Стр);
Стр:="Ответ на любую информацию";
Сокет.SendStr(Стр,1);
//Далее следует обмен любой другой информацией
Finally
//Разрываем соединение, чтобы система не ждала продолжения
SuppressException();
Сокет.Disconnect();
EndTry;
EndFunction