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