СЕТЕВОЕ ПРОГРАММИРОВАНИЕ

Это учебная книга по программированию для сетевой робототехники. Архитектура системы включает, соответственно, сервер, клиент, робот. Робот предствляет собой сенсорную сеть (датчики) и эффекторы (моторы, приводы, манипуляторы). Робот может быть один или их может быть несколько. Пространственно он может находится в одном месте, или причудливо распределен. Робот может быть реальным, виртуальным, смешанным. Специалист по робототехнике должен быть полиглотом: разнообразие языков программирования следует из обилия весьма различных между собой проблем, встречающихся при построении сетевых роботов.

Примечание. Примеры написаны для браузера Internet Explorer, для начальных опытов это не имеет значения, но более сложные возможности иллюстрируются и отлажены для этого браузера. В FireFox, например, не работает синхронный запрос в ajax (если используется синхронный запрос - это уже sjax). В этих случаях не следует использовать обработчик событий onreadystatechange, а просто после метода send() нужно "снимать результат".

ОГРАНИЧЕНИЯ СИСТЕМЫ ЭЛЕКТРОННЫХ КНИГ

Выделенные php-скобками части большой программы исполняются независимо по eval, между фрагментами нет передачи переменных и межфрагментное пространство никак не используется. Комментарии php употребляются в закрытом виде /* комментарий */.


<? php-коды обработки ?>форма<? php-коды подготовки ?>интерфейс

Форма окна вывода вставляется автоматически после первого фрагмента php-кодов с идентификатором id="mainForm" и атрибутами method=POST enctype=multipart/form-data. Это упрощает написание программ, поскольку для обеспечения функциональности форма сложна для ее написания вручную. В целях безопасности договоримся в CGI интерфейсах textarea заменять на text-area (защита области редактирования), не употреблять напрямую операторы ввода-вывода и не менять URL папки обрабатываемых изображений: records/images/image.jpg.

ЯЗЫКИ ПРОГРАММИРОВАНИЯ

Для программирования серверов употребляются серверные языки, распространен php. Интерфейс клиентской части пишется обычно с использованием cgi и javascript. Математические алгоритмы выгоднее писать на языке матричного исчисления, например, MatLab. Для взаимодействия с роботами целесообразно употреблять адаптированные серверную iMatLab и клиентскую Visual MatLab модификации. Микропроцессоры роботов чаще программируются на усеченной версии языка си: C-шарп, AVR GCC и прочие. Значительную помощь нам окажет то, что на страницах сетевой книги можно располагать не только примеры, но и исполняемые алгоритмы. Рекомендуемые справочники и учебники.

CGI | Сайт Html-book | Справочник HTML | Справочник PHP | [2] [СЕССИИ]
Справочник Javascript | Связка PHP-Javascript | Технология Аякс
Mobilab (J2ME) | Microsoft | ASP | С# | putty

ПРОГРАММИРОВАНИЕ AVR

Chipenable | Easyelectronics | 123avr

СЕТЕВЫЕ РЕСУРСЫ С ИСПОЛНЯЕМЫМИ АЛГОРИТМАМИ

iMatLab vMatLab PHP-JS AVR-GCC J2ME

ИСПОЛНЯЕМЫЕ В СЕТИ АЛГОРИТМЫ

Математические алгоритмы вводятся тэгом math в квадратных скобках. Сетевой iMatLab помимо прочего эмулирует на клиентской машине AVR-микропроцессор, программируемый в среде AVR-GCC, и выводит графическое изображение отладочной платы или робота с AVR-микропроцессором. На эту тему написана отдельная книга. Для php и javascript в тех же скобках применяется тэг code. Запросим, например, версию обслуживающего нас php-транслятора.


<? phpinfo(); ?> ЗАПРОС ВЫВОДА ВЕРСИИ PHP НА СЕРВЕРЕ

Cодержимое, заключенное между тэгами [code] ... [/code], выполняется на двух компьютерах. Часть, исполняемая на сервере, окаймлена косыми скобками со знаком вопроса. Текст вне скобок обрабатывается на клиентском компьютере и отображается на экране браузером с использованием html-форматирования. В том случае, если он содержит javascript-коды, код выполняется. Сосредоточимся ниже на сугубо сетевых языках программирования.

CGI-ИНТЕРФЕЙС

Еще на заре создания оконной системы в Windows сформировались ресурсы, к которым нужно обратиться для того, чтобы увидеть на форме вывода кнопки, переключатели, окна ввода и вывода текста. Правила составления обращения для интернета чрезвычайно упрощены, см. CGI-интерфейса. Особое значение имеет кнопка (input) типа submit страницы P1, она вызывает на исполнение страницу P2, указанную атрибутом action формы ее сетевым адресом.

Помимо адреса P2 на сервер отсылаются заполненные у клиента поля ввода информации P1. Серверная программа на PHP, содержащаяся на странице P2, имеет доступ к информации клиента и к информации на сервере, обрабатывает ее и формирует ответ P2. Довольно часто страница вызывает самою себя, как показано ниже (исходные данные и итог размещаются на одной и той же странице), при этом приходится различать стартовый момент, когда страница запускается впервые

Рассморим пример. Атрибутами тэга form указаны имя формы mainForm и метод передачи данных POST, т.е. скрытная передача данных окон клиента "почтой". Существует более открытый (упрощенный) метод передачи GET, когда данные приписываются после вопросительного знака к адресу запускаемой страницы. Атрибут action опущен, страница будет вызывать самою себя.


<? if (isset($_POST['press'])) echo 'Привет, '.$_POST['str'].'!'?>
<form id="mainForm" method=POST enctype=multipart/form-data>
<input type='text' name='str' value='введите тут имя'</>
<input type='submit' name='press' value='Передать данные на сервер'>

В системе электронных книг тэг формы добавляется автоматически, он несколько сложнее указанного, его можно не писать. Помимо, в CGI интерфейсах textarea заменяется на text-area (защита области редактирования). Тип, имя и значение ресурсов страницы вводятся атрибутами type, name и value. В программе обращением к input формируются текстовое окно ввода типа text со значением value и кнопка активизации процесса перезагрузки страницы типа submit.

PHP-программа, обрабатывающая переданные данные, размещается тут в самом начале, ее коды окаймляются косыми скобками (тэгами) с вопросительными знаками. Процедура isset() проверяет, заполнен ли буфер. На старте он не заполнен и ничего не происходит. При ротировании страницы есть смысл буфер читать. Чтение буфера переданных по POST данных происходит обращением $_POST['имя окна']. Как видно, в программе проверяется, нажата ли кнопка press.

Таким образом, можно вводить несколько кнопок типа submit с разными именами и организовывать для каждой свою обработку.

В данном случае кнопка одна (вы можете добавить сами еще такие кнопки, тренируясь). Если она нажата, сервер, следуя php-программе, добавляет приветствие (Привет) к содержимому текстового окна по имени str и выводит его на страницу командой echo. Строки текста соединяются в PHP (в отличие от javascript) точкой. Почему точкой, а не привычным сложением? Браузеру проще разобраться в обилии обрабатываемых разноязычных кодов тогда, когда синтаксис языков специфичен. Нажмите старт, посмотрите, как работает исполняемый алгоритм. Потренируйтесь с ним на учебном форуме.

ОБМЕН С СЕРВЕРОМ

Монополия php сложилась, поскольку javascript создавался как язык с жесткими ограничениями на обмен информацией с дисками клиента или сервера. Со временем эта мера безопасности стала стеснять разработчиков, возникла технология ajax прямой связи A между компьютерами сети (сервером и клиентом)

Опираясь на CGI, сформируем интерфейс ввода-вывода вида

и обеспечим обмен данных между окнами через сервер. Тип нажимаемой кнопки button отличается от submit, перезагрузки страницы не происходит. По value формируются надписи на них. При нажатии происходит обращение к указанным по onclick javascript-подпрограммам, исполняемым компьютером клиента. Это ускоряет процесс обработки, нет перезагрузки страницы. Первая кнопка сбрасывает данные первого текстового окна на сервер. Вторая кнопка - считывает их. Строка имени считываемого файла модифицируется рандомизированной опцией запроса фиктивных данных с ? для того, чтобы при повторном клике на чтение браузер брал данные не из кэша на вашем компьютере, а именно с сервера.


<? /* обработка ведется клиентом */ ?>
<form id="mainForm" method=POST enctype=multipart/form-data>
<input type="text" id="out" value=0>
<input type="button" value="write" onclick=ajaxWrite()>
<input type="button" value="read" onclick=ajaxRead()>
<input type="text" id="inp">

<script language='JavaScript'>

var buffer=0;

function ajaxWrite(){  
 var xmlObj = null;  
 var contentType = "application/x-www-form-urlencoded; charset=UTF-8";  
 if(window.XMLHttpRequest){  
 xmlObj = new XMLHttpRequest();  
 } else if(window.ActiveXObject){  
 xmlObj = new ActiveXObject("Microsoft.XMLHTTP");  
 } else { return; }  
 xmlObj.open('POST','records/data/putdata.php',true);  
 xmlObj.setRequestHeader("Content-Type", contentType);
 /* ВЗЯТЬ ДАННЫЕ ИЗ ОКНА out */ 
 var data=document.getElementById('out').value;  
 /* ПЕРЕСЛАТЬ НА СЕРВЕР В ФАЙЛ file.xml */ 
 xmlObj.send('password=file&data='+data);  
}  
  
function ajaxRead(){  
 var xmlObj = null;  
 if(window.XMLHttpRequest){  
  xmlObj = new XMLHttpRequest();  
 }else if(window.ActiveXObject){  
  xmlObj = new ActiveXObject("Microsoft.XMLHTTP");  
 } else { return; }  
 /* ПРОГРАММА ОБРАБОТКИ ПРЕРЫВАНИЯ ПО ПРИХОДУ ДАННЫХ */ 
 xmlObj.onreadystatechange = function(){  
 if(xmlObj.readyState == 4){
  /* ПРОЧИТАТЬ ДАННЫЕ В buffer */ 
  buffer=xmlObj.responseXML.getElementsByTagName('data')[0].firstChild.data; 
  /* РАЗМЕСТИТЬ ДАННЫЕ В ОКНЕ inp */ 
  document.getElementById('inp').value=buffer; 
 }} 
 /* УКАЗАТЬ ФАЙЛ ДЛЯ ЧТЕНИЯ (РАНДОМИЗИРОВАННОЕ ИМЯ) */ 
 xmlObj.open('GET','records/data/file.xml'+"?"+Math.random(),true);  
 xmlObj.send ('');  
}
  
</script>

Можно обойтись и без сбрасывания на сервер, но мы этот процесс изучаем. В отличие от устоявшихся языков программирования, процедуры записи (write) и чтения (read) пишет сам пользователь на основе указанных штампов. Это позволяет несколько менять их работу. Ключом true в open команды переводятся в асинхронный режим работы: когда исполнение программ не останавливается на завершении операций удаленного серверного чтения или записи. Иначе возникает ощутимый тормоз при работе со страницей. В FireFox вообще не работает синхронный запрос (если используется синхронный запрос по false - это уже sjax). В этих случаях не следует использовать обработчик событий onreadystatechange, а просто после метода send() можно "снимать результат". Штамп зубрить или разбирать подробно не надо, он употребляется целиком, как данность.

Процедуры заметно несимметричны. Более опасна для спама операция записи на сервер.Файл обмена file.xml содержит записываемые на сервер текстовые данные. Команда чтения, как видно, к нему напрямую обращается, итог чтения передается в текстовое окно с именем 'inp'. Команду записи так оформить нельзя (писать напрямую в файл), иначе в file.xml будут записывать данные не только мы, но и любой спаммер.

На сервере хозяином его размещается программа посредник, в данном случае putdata.php. Программа записи вызывает ее и передает ей данные из окна с именем 'out' и пароль password. Программа putdata.php первым делом проверяет пароль. Так как эта программа пишется хозяином сервера, он может закладывать в нее любые сколь угодно сложные процедуры проверки пароля. Спаммеру вход прикрыт. Если все в порядке, то putdata.php записывает переданные данные в файл file.xml. На внешнюю сложность подпрограмм чтения-записи едва ли стоит обращать внимание. Широкая вариативность - обычное свойство интернет средств, ориентированных на многозадачность. Доступ к содержимому (value) окон интерфейса по их идентификаторам id обеспечивает процедура getElementById(идентификатор). Чтобы побудить браузер заново скачать данные (а не читать старые из буфера), наименование файла меняем добавкой случайного числа, причем в асинхронном режиме буфер buffer загружается по мере поступления информации.

Для сохранения данных на сервере используется текстовой формат. Предпочтителен его xml-вариант, когда тэгами помечаются версия формата, его параметры, начало базы данных root и ее столбцы data.


<?xml version="1.0" encoding="UTF-8"?><root><data>данные</data></root>

Запись производится программой putdata.php, проверяющей наличие пароля password и создающей xml-файлы заданного вида. На учебном сервере она уже есть, поэтому заботиться о ней не надо.


<? 
if (isset($_POST["password"])){ 
$name=$_POST["password"].".xml"
$message=StripSlashes('<?xml version="1.0" encoding="UTF-8"?><root><data>'.$_POST["data"].'</data></root>'); 
$deleted unlink($name); 
$filems fopen($name,"a+"); 
$written fwrite($filems,$message); 
fclose($filems); 

?> 

ВЫВОД ГРАФИКИ

Графика играет большую роль при написании интерфейсов. Приведем отладочный пример с полупрозрачными изображениями квадратов. Назначим цвета и альфа-канал (прозрачность) второго из них. Обратите внимание, что обозначения переменных и массивов в php начинается со знака $. Заголовок header определяет способ сжатия изображения (png).


<? header('Content-Type: image/png');
  
$image imagecreatetruecolor(200,200);  
  
$col imagecolorallocate($image0x990xFF0xFF);
  
imagefilledrectangle($image00100100$col);
  
$col imagecolorresolvealpha($image0x990x990xFF50);
  
imagefilledrectangle($image00150150$col);
  
imagejpeg($image);
?>

В программе генерируется изображение $image со сторонами 200. Тремя (красный-зеленый-голубой) RGB-составляющими в шестнадцатиричной системе счисления 0x (цифры 0, 1, ... 9, A, B, ... E, F) задается цвет $col. Этим цветом заполняется квадрат со стороной 100. Тремя RGB-составляющими и прозрачностью задается новый параметр раскраски. Поверх рисуется еще один квадрат со стороной 150. Последний оператор выводит изображение на экран дисплея.

ВЫВОД ФОТОГРАФИИ

В данном случае с диска читается готовое изображение. Процедура чтения размеров фотографии GetImageSize(имя) формирует вектор, в котором помимо размеров указан и номер типа файла. Символ @ употребляется для разрешения неопределенности на тот случай, когда имя фотографии задано с ошибкой: по default возвращается квадрат стороною 200. Знание типа файла позволяет применить соответствующую процедуру чтения. Результат работы подпрограммы выведем на экран.


<?
function getimg($name) {
/* подпрограмма чтения изображения */
if($pms = @GetImageSize($name)){
      switch (
$pms[2]){
       case 
:  $image imagecreatefromgif($name); break;
       case 
:  $image imagecreatefromjpeg($name); break;
       case 
:  $image imagecreatefrompng($name); break;
       case 
:  $image imagecreatefromwbmp($name); break;
      default :  
$image imagecreatetruecolor(200,200); 
}}
return 
$image;
}

$image getimg('records/images/makarov.jpg');
header('Content-Type: image/jpeg');
imagejpeg($image);
?>



Rambler's Top100