пятница, 5 марта 2021 г.

Эксперименты с соединением TCP

Экспериментируя с приложением Termux на телефоне, увидел что там есть утилита ncat, которая может записывать и читать данные по сети из командной строки. Соединение может устанавливаться по разным протоколам: tcp, udp,telnet и работать может как в качестве сервера (то есть принимать запросы и отвечать на них), так и в качестве клиента (отправлять запросы и получать ответы). Довольно интересно было соединить смартфон с компьютером по локальной сети и посмотреть как они обмениваются информацией. Чтобы это сделать можно использовать общий WiFi или включить телефон в качестве точки доступа и с компьютера подключиться к ней. В термуксе я запустил прослушивание порта командой nc -l 8877 (l значит listen, а номер порта можно выбрать вообще любойа на компьютере установил соединение с телефоном через клиент Putty, где указал IP адрес телефона и тот самый порт 8877. Формат соединения Raw, то есть простой TCP/IP
^ Это то что было видно на клиенте
^ А это то что было на сервере, то есть на телефоне 
Получился такой своеобразный чат. На самом деле все это особого смысла конечно же не имеет, и делалось просто чтобы узнать что это за команда такая, и как она работает. По сути смартфон сейчас может заменять компьютер и может устанавливать соединение с любым сервисом. Как-то раз нам по работе нужно было принимать сигналы из весового модуля в контроллер по соединению TCP и чтобы узнать структуру посылаемых данных, мы предварительно подключились к нему через Putty таким же методом. Собственно как показывает этот эксперимент можно было бы воспользоваться и смартфоном с термуксом. Ну а вообще есть куча программ в плей маркете, которые специально предназначены для проверки TCP соединения, например TCP терминалы или клиенты.

А еще мне стало интересно, что же посылает браузер, когда запрашивает через интернет страницу с сервера. Для этого я так же запустил команду на прослушивание порта в термуксе и через браузер открыл страницу по адресу IP телефона. Тут же в термуксе появился весь текст запроса, который был отправлен из браузера, который как положено содержал в себе метод, хост и заголовки. 

Сервер по этим данным определяет что хочет получить браузер и в каком виде и посылает в ответ аналогичную структуру, где содержится метод, заголовки и тело ответа. В качестве ответа я заслал страничку которая генерирует матрицу


В качестве ответа сервера я посылал вот этот код:

HTTP/1.0 200 OK
Date: Fri, 05 Mar 2021 00:15:45 GMT
Connection: close
Content-type: text/html

<body style=margin:0>
<canvas id=q />
<script>
        var q=document.getElementById('q'),s=window.screen,w=q.width=s.width,h=q.height=s.height,p=Array(256).join(1).split(''),c=q.getContext('2d'),m=Math;
        setInterval(function(){
                c.fillStyle='rgba(0,0,0,0.05)';
                c.fillRect(0,0,w,h);
                c.fillStyle='rgba(0,255,0,1)';
                p=p.map(function(v,i){
                        r=m.random();
                        c.fillText(String.fromCharCode(m.floor(2720+r*33)),i*10,v);
                        v+=10;
                        return v>768+r*1e4?0:v
                })
        },33)
</script>
Ну напоследок небольшой код TCP клиента в C# который только принимает данные определенной структурой, где в начале и конце есть символы начала и конца строки, а сами данные разбиты между собой группами разделенные точкой с запятой
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.Net;

namespace UDPcamera
{
    class Program
    {
        private const int port = 8000;
        private const string server = "192.168.100.19";

        static void Main(string[] args)
        {
            try
            {
                TcpClient client = new TcpClient();
                client.Connect(server, port);
                byte[] data = new byte[40];
                StringBuilder response = new StringBuilder();
                NetworkStream stream = client.GetStream();

                do
                {
                    int bytes = stream.Read(data, 0, data.Length);
                    // response.Append(Encoding.UTF8.GetString(data, 0, bytes));
                    string str = Encoding.UTF8.GetString(data, 0, bytes);
                    string str2 = str.Remove(0,1).Replace(" ", ""); //удалить первый символ и убрать все пробелы
                    string[] value = str2.Replace("0", "0;").Split(';'); // разбить строку на массив строк разделенные ;
                    for (int i=0;i<10;i++) Console.WriteLine(value[i]);
                }
                while (true);// stream.DataAvailable); // пока данные есть в потоке

                // Закрываем потоки
                stream.Close();
                client.Close();
            }
            catch (SocketException e)
            {
                Console.WriteLine("SocketException: {0}", e);
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception: {0}", e.Message);
            }
            Console.WriteLine("Запрос завершен...");
            //Console.Read();
        }
    }
}

Комментариев нет:

Отправить комментарий