Ничего не может так скрасить воскресный вечер, как изобретение очередного велосипеда. Зато своего, собственного. На этот раз мы напишем простой сервер на bash, используя утилиту nc. А там, где сервер — там и клиент, так что в добавок мы напишем простой клиент для Android на Java к нашему серверу. Можно было-бы обойтись и браузером, но как тогда хвастаться перед друзьями, что у нас есть свой софт для мониторинга своего ПК на OS Linux?
Вступление
Результатом сегодняшней статьи станет небольшое клиент-серверное решение задачки удаленного мониторинга состояния компьютера под управлением OS Linux. Мы получим возможность следить за температурой компьютера и выполняемыми в данный момент процессами. Для клиентской части не понадобиться иметь терминал.. по большому счету — ничего кроме браузера и не понадобится. Но простой клиент мы все-же сделаем — для удобства и морального удовлетворения ради. В решении этой задачи нам помогут утилита NetCat и Android (телефон-то всегда под рукой).
NetCat — это утилита для Linux, позволяющая устанавливать соединения TCP и UDP, принимать и передавать данные. Эта довольно простая в обращении утилита, однако, имеет достаточно большой потенциал для ее применения в повседневной жизни. С ее помощью можно организовать чат между двума рабочими станциями, передать файл или даже весь жесткий диск. Но сегодня нам понадобиться ее возможность создавать соединение на определееном порту и слушать его — тоесть, служить сервером.
Также, если у тебя есть желание самому скомпилировать утилиту-клиент для Android, которую мы сегодня напишем — тебе понадобится среда разработки Eclipse (или любая другая), но примеры в статье будут именно для Eclipse. Заострять внимание на установке IDE я не буду — скачать готовую сборку для программирования под Android можно на сайте: https://developer.android.com/sdk/index.html (Программа бесплатная, без регистрации и смс 🙂 ). Можешь, впрочем, и не качать тяжелую среду разработки и всякие sdk — в конце статьи я выложу уже готовую к использованию утилиту apk.
Серверная часть
Серверная часть нашей конструкции будет до безобразия простой. Настолько простой, что сам сервер будет состоять из скрипта в одну строку. И такой подход не случаен, ведь когда ты прибегаешь к подобным решениям текущих задач, задач достаточно тривиальных — то немаловажным условием является быстрая из реализация. Т.е. так, между делом: попил кофе, накатал сервак…
Собственно, сам сервер:
#!/bin/bash while true; do { echo -e 'HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n'; bash load_with_html.sh; } | nc -l 1488; done
Тоесть при обращении к серверу (nc) мы просто отдаем заголовки что все в порядке (200), и что отдаем мы HTML код — браузер это хава.. принимает и выводит то, что отдаст ему скрипт load_with_html.sh. Сервер я запускаю на порту 1488 — это ничем не обусловлено, на самом деле мне просто захотелось использовать именно этот порт и это совершенно не значит, что я националист или другой «ист» 🙂 Ты можешь поменять адрес порта в зависимости от потребностей (например, если 1488 уже занят у тебя другим сервисом).
Итак, берем скрипт, что выше, сохраняем его в файл, допустим, ~/Tools/miniserv.sh, даем ему права: chmod +x ~/Tools/miniserv.sh и, затем, создаем файл-скрипт: ~/Tools/load_with_html.sh в котором сформируем данные для вывода. Выведем в нем пару полезных параметров системы и оформим все красивенько — с помошщью HTML, CSS и JavaScript.
load_with_html.sh:
#!/bin/bash echo "<!DOCTYPE HTML>" echo "<html>" echo "<head>" echo "<title>My Linux PC State</title>" echo "<style type=\"text/css\">" echo "div.sensors {" echo " font-size: 38px;" echo " color:#000000;" echo " background-color: #DCF7FF;" echo " text-align:center;" echo " border:1px dotted;" echo " margin-bottom:8px;" echo "}" echo "pre {" echo "width:100%;" echo "overflow: auto;" echo "}" echo "#hide_sensors {" echo " display: none;" echo "}" echo "#hide_uname {" echo " display: none;" echo "}" echo "#hide_proc {" echo " display: none;" echo "}" echo "</style>" echo "<script type=\"text/javascript\">" echo " function hideme(id){" echo " if(document.getElementById(id).style.display == 'block') {" echo " document.getElementById(id).style.display = 'none';" echo " } else {" echo " document.getElementById(id).style.display = 'block';" echo " }" echo " }" echo "</script>" echo "</head>" echo "<body>" ##Uname echo "<div class=\"sensors\" onClick=\"hideme('hide_uname');\">" echo "Linux version" echo "</div>" echo "<div id=\"hide_uname\" style=\"display: none;\">" echo "<pre>" uname -a echo "</pre>" echo "</div>" ##Sensors echo "<div class=\"sensors\" onClick=\"hideme('hide_sensors');\">" echo "Sensors" echo "</div>" echo "<div id=\"hide_sensors\" style=\"display: none;\">" echo "<pre>" sensors echo "</pre>" echo "</div>" ##Processes echo "<div class=\"sensors\" onClick=\"hideme('hide_proc');\">" echo "Processes" echo "</div>" echo "<div id=\"hide_proc\" style=\"display: none;\">" echo "<pre>" ps -ela echo "</pre>" echo "</div>" echo "</body>" echo "</html>"
По образу и подобию приведенных в коде выше выводов программ ты можешь добавить туда собственные выводы, например, статус игрового сервера или еще чего.
На этом с серверной частью полностью покончено — осталось протестировать ее работоспособность. В терминале выполни скрипт miniserv.sh:
cd ~/Tools ./miniserv.sh
И для проверки обратись через браузер по адресу: 127.0.0.1:1488 . Если все прошло хорошо, то ты увидишь следующую станичку (информация будет открываться при клике на соответствующие пункты):
Клиентская часть (Для продвинутых)
Впринципе, клиентскую часть создавать совершенно не обязательно — можно уже обращатся к своему компьютеру через браузер по адресу ip:port, но без нее, согласись, все это выглядит каким-то незавершенным. К тому-же клиент для телефона писать от силы десять минут.
Далее я предполагаю, что IDE у тебя установлена и представление о том, что это такое ты имеешь. Если нет — то ее установка и настройка выходит далеко за рамки данной статьи и в таком случае предлагаю пропустить выложенный ниже исходный код и сразу скачать готовое приложение в конце статьи.
Отлично, Eclipse запущен. Выбираем в меню: File->New->Android Application Project (создаем новый проект) и заполняем последовательно по примерам на скриншотах ниже:
Обрати внимание — в меню Eclipse — Window->Sdk manager должны быть установленны соответствующие версии SDK.
В файле AndroidManifest.xml не забываем указать:
<uses-permission android:name="android.permission.INTERNET" />
Содержимое файла MainActivity.java:
package com.maddot.twmp_linux; import android.app.Activity; import android.content.pm.ActivityInfo; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.webkit.WebView; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity { WebView myWebView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); Button nowGet = (Button)findViewById(R.id.button1); nowGet.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub TextView ipGet = (TextView) findViewById(R.id.ip); String ip = ipGet.getText().toString(); TextView portGet = (TextView) findViewById(R.id.port); String port = portGet.getText().toString(); myWebView = (WebView) findViewById(R.id.webView1); myWebView.getSettings().setJavaScriptEnabled(true); myWebView.setHorizontalScrollBarEnabled(false); myWebView.loadUrl("http://"+ip+":"+port); } }); } }
Содержимое файла activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="${packageName}.${activityClass}" > <EditText android:id="@+id/ip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:ems="10" android:hint="0.0.0.0" /> <EditText android:id="@+id/port" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_toRightOf="@+id/ip" android:ems="10" android:hint="port" android:text="1488" > <requestFocus /> </EditText> <Button android:id="@+id/button1" style="?android:attr/buttonStyleSmall" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/ip" android:text="Connect and show info" /> <WebView android:id="@+id/webView1" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/button1" android:layout_centerHorizontal="true" /> </RelativeLayout>
Как должен выглядить интерфейс:
Идея в том, чтобы эта утилита обладала достаточной универсальностью и простотой — вверху в поля ввода можно указать IP и Порт компьютера и после клика на кнопку в WebView браузер загрузится ответ сервера — то, что нужно, просто и удобно.
Отлично, часть для продвинутых читателей закончена (осталось только собрать проект и скинуть его на телефон или протестировать на эмуляторе).
А для тех, кому не хочется/не нужно разбираться со всеми этими Java’ми:
Клиентская часть (Для всех)
Скачать утилиту-клиент TWMP-Linux для Android:
https://maddot.ru/share/files/1412521621_twmp-linux.apk [~777 Kb]
Итак, последовательность использования того, что мы сегодня сделали:
- Запускаем на ПК сервер: cd ~/Tools -> ./miniserv.sh & (&, чтобы терминал вернул курсор ввода)
- Когда нужно посмотреть, что там с компьютером — Запускаем TWMP-Linux или заходим через браузер на ip:port компьютера
Profit!
Правильные ли здесь кавычки?
uses-permission android:name=»android.permission.INTERNET» />
Разумеется нет, здесь нужны простые двойные
"
кавычки, спасибо за внимательность — поправил.