Обработка inband-команд
Буфер CMD
Все входящие inband-команды сохраняются в буфере CMD. В любой момент в буфере может быть больше одной команды. У каждого inband-сообщения в буфере уже удалены escape-символ и следующий за ним символ. Завершающий символ, однако, не удаляется, и программа может использовать его, чтобы отделять inband-сообщения друг от друга.
Пример. Допустим, у вас такая настройка:
...
sock.inbandcommands= YES
sock.escchar=`@`
sock.endchar=`&`
...
Вот пример потока данных:
Этот входящий поток данных даст такой результат:
- Буфер RX получит данные: «DataMoredataEvenmoredata»
- Буфер CMD получит: «ommand1&command2&»
Обратите внимание: в первой inband-команде не хватает первого символа - дело в том, что при обработке inband-команды удаляются и её escape-символ, и следующий за ним символ. Завершающие символы обеих inband-команд сохраняются, чтобы можно было определить, где кончается каждая из них.
Извлечение данных из буфера CMD
Извлечение данных из буфера CMD похоже на извлечение данных из буфера RX. Эту работу выполняет отдельный метод - sock.getinband. Он работает так же, как sock.getdata, только без аргумента maxinplen. Общий объём данных в буфере CMD можно узнать из свойства только чтение sock.cmdlen.
После извлечения данных в буфере уже нет. Свойство sock.cmdlen позволяет проверить, сколько данных ожидает в буфере CMD. Отдельного свойства для размера буфера нет - если он вам нужен, просто запомните, что вернул метод sock.cmdbuffrq!
Событие on_sock_inband генерируется, когда в буфере CMD есть данные, но только один раз. В очереди никогда не бывает двух событий on_sock_inband. Следующее событие генерируется только после завершения обработки предыдущего, если к тому времени в буфере CMD есть данные.
Inband-команды появляются в буфере CMD только целиком. То есть если буфер был пуст и вы получили событие on_sock_inband, то гарантируется, что в буфере лежит полная команда (или несколько полных команд).
Пример:
sub on_sock_inband
dim s as string 'we will keep the data from the CMD buffer here
dim s2 as string 'this will keep individual inband commands
dim x as byte
s=sock.getinband 'we get entire CMD buffer contents into the s
x=instr(1,s,chr(sock.endchar))
while x<>0
s2=left(s,x-1) 's2 now contains a single inband command
s=right(s,len(s)-x) 'cut out this command
'process inband command in the s2 as needed
...
...
'any more inband commands to process now?
x=instr(1,s,chr(sock.endchar))
wend
end sub
Чтобы этот пример работал хорошо, размер буфера CMD не должен превышать ёмкость строковой переменной s. Тогда всё, что извлечено из буфера CMD, всегда поместится в s. Если буфер больше ёмкости s, потребуется немного более сложная обработка.
Возможно ли переполнение буфера CMD?
Переполнение буфера CMD невозможно. Если сокет получает inband-команду, которую нельзя сохранить в буфере CMD целиком, он отбрасывает всю команду (программа никак об этом не уведомляется). Поэтому вы всегда получаете inband-команды либо полностью, либо не получаете их совсем.
Неполные inband-команды
Посмотрите на этот поток данных:
Здесь inband-команда неполная: новая inband-команда начинается до окончания предыдущей. Такие неполные команды отбрасываются и в буфер CMD не записываются.