ZP+TCP/IP Передаем статус проекта на мобильное устройство

Serkser

Client
Регистрация
26.01.2015
Сообщения
90
Благодарностей
343
Баллы
53
Всем доброго дня!
В этой статье я бы хотел Вам рассказать о таком протоколе передачи данных как TCP/IP и как его можно использовать в своих проектах.

Чуть чуть теории
Переводя определение с википедии, можно сказать что этот протокол позволяет серверу и клиенту установить один общий буффер данных, в который любая из сторон может вписывать информацию, а другая получить уведомление об этом и прочитать ее + TCP гарантирует доставку всех пакетов без потерь в отличии от UDP.

Ближе к делу
В моем примере сервером будет выступать шаблон ZP, а клиентом станет мобильное приложение.
Хотя на самом деле клиента можно написать и на другом шаблоне и обмениваться данными между ними даже если они физически находятся в двух разных уголках планеты =)

Для создания шаблона- сервера нам понадобится библиотека Interop.NATUPNPLib (во вложении). Она необходима для того чтобы пробросить порт через ваш локальный IP адрес и роутер, который имеет внешний IP адрес, чтобы вы смогли подключаться к своему проекту через интернет, а не только находясь в одной локальной сети.

Добавляем ссылку на библиотеку в шаблон и начинаем кодить:
Во вкладке общего кода у вас должны быть следующие using
Код:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text.RegularExpressions;
Объявляем нужные нам переменные:

Код:
         static NATUPNPLib.UPnPNAT upnpnat = new NATUPNPLib.UPnPNAT();
         static IPAddress ipAd;
         static TcpListener listener;
         static Socket socket;
Первый метод для получения своего локального адреса
Код:
public static IEnumerable<IPAddress> GetLocalIPAddress()
        {
           return Dns.GetHostEntry(Dns.GetHostName()).AddressList.Where(f=> f.AddressFamily == AddressFamily.InterNetwork);
        }
Далее метод для получения статуса соединения
Код:
public static bool IsConnected(this Socket sockets)
         {
           try
           {
             return !(sockets.Poll(1, SelectMode.SelectRead) && sockets.Available == 0);
           }
           catch (SocketException) { return false; }
         }
Самый важный метод - запуск сервера и старт ожидания соединения
Код:
public static bool StartConnection()
        {
            string ipAddres = string.Empty;
            if (GetLocalIPAddress().Any()) //получаем свой локальный ip адрес
                ipAddres = GetLocalIPAddress().First().ToString();
            else
                return false;
             ipAd = IPAddress.Parse(ipAddres);
             listener = new TcpListener(ipAd, 20903);
             listener.Start();// запуск сервера
            // делаем проброс порта через роутер
            NATUPNPLib.IStaticPortMappingCollection mappings = upnpnat.StaticPortMappingCollection;
            if(mappings !=null)
            mappings.Add(20903, "TCP", 20903, ipAddres, true, "Port for ZennoPoster"); //если требуется пробрасываем порт
          new Thread(()=> socket = listener.AcceptSocket()).Start(); // ожидание подключения в фоновом потоке
            return true;
        }
Как можно увидеть в этом методе мы устанавливаем соединение нашего сокета (можно сказать что это канал передачи данных) с удаленным сокетом, который захочет к нам подключиться

Метод передачи сообщения
Код:
//метод отправки сообщения клиенту
        public static bool SendMessage(string text)
        {
            if(socket ==null)
                return false;
            try{
            byte[] bytes = Encoding.GetEncoding(1251).GetBytes(text);
            socket.Send(bytes);
                return true;
            }
            catch{return false;}
            finally{
            if(!socket.IsConnected() && socket != null)
            {StopConnection();
                StartConnection();
            }
            }
        }
Грубо говоря мы просто взяли текст, перевели его в массив байтов и отправили по сокету

Отправка файла, а в нашем случае мы будем отправлять каптчу
Код:
//метод отправки файла клиенту
        public static string SendCaptcha(string filePath)
        {
            if(socket ==null)
                return "";
            try{
            byte[] bytes = Encoding.GetEncoding(1251).GetBytes("isFile "+File.ReadAllBytes(filePath).Length);
            socket.Send(bytes);
            socket.Receive(bytes);
            socket.Send(File.ReadAllBytes(filePath));
            bytes = new byte[1024];
           int lenght= socket.Receive(bytes);
            return Encoding.GetEncoding(1251).GetString(bytes);
            }catch{return "";}
            finally{
            if(!socket.IsConnected() && socket != null)
            {StopConnection();
            StartConnection();
            }
            }
        }
Тут по сложнее. В коде можно увидеть две отправки пакета байтов, первым я передаю флаг в виде слова "isFile" + размер файла, который я собираюсь передать. Далее ожидаю ответа от клиента и уже отправляю чистый файл, переведенный в массив байтов. Зачем такой кастыль?) Да потому что стандартный метод передачи файла по сокету почему то убивает PM, поэтому я решил сделать вот так. Да и везде говорят что при таком подходе быстрее файл передается чем уже готовым методом =)

Ну и последний метод закрытия соединения
Код:
        //метод остановки соединения
        public static void StopConnection()
        {
            try{
            if(socket!= null)
            socket.Disconnect(true);
            if(listener!= null)
            listener.Stop();
            NATUPNPLib.IStaticPortMappingCollection mappings = upnpnat.StaticPortMappingCollection;
            mappings.Remove(20903, "TCP");
            }catch{}
        }
Суть написания клиента
В первую очередь на клиенте нужно произвести соединение с сервером:
Код:
               IPEndPoint ipep =
                   new IPEndPoint(IPAddress.Parse("Внешний ip сервера"), 20903);
               Socket server = new Socket(AddressFamily.InterNetwork,
                   SocketType.Stream, ProtocolType.Tcp);
                       await server.ConnectAsync(ipep);
Для того чтобы дождаться и получить данные от сервера делаем так
Код:
byte[] data = new byte[1024]; //готовим массив, куда будет сложен ответ
                      int lenght = socket.Receive(data); //наполняем этот массив, одновременно получая его длину
                      string text = Encoding.GetEncoding(1251).GetString(data, 0, lenght);// переводим массив в строку
Отправка данных от клиента к серверу
Код:
       byte[] dataBytes = Encoding.GetEncoding(1251).GetBytes("текст который передаем");
                    socket.Send(dataBytes); //отправляем
Таким образом на выходе получаем следующее:
Как видно в демонстрации на телефоне у меня обычное мобильное соединение, а на ПК домашний WIFI, данные передаются достаточно быстро=)

Исходники клиента можете скачать или посмотреть тут (Xamarin):
https://bitbucket.org/serkser70/clientzp

Запакованый APK клиента (форум не принимает apk файлы, залил на яндекс):
https://yadi.sk/d/6PBUMW4K3N9rzD

Библиотека:
https://yadi.sk/d/bVgw5GPl3N9ryh

На этом все =)

Я понимаю что для некоторых эта статья покажется слишком мудреной и сложной, но тем не менее искренне верю, что кому то это откроет новый взгляд на построение своих проектов и поможет реализовать крутые идеи!
А для новичков это не лишнее доказательство безграничных возможностей ZennoPoster!

Всем огромное спасибо за внимание! Я очень рад снова участвовать в этом конкурсе!=)
 
Тема статьи
Другое
Номер конкурса статей
Седьмой конкурс статей

Вложения

Для запуска проектов требуется программа ZennoPoster или ZennoDroid.
Это основное приложение, предназначенное для выполнения автоматизированных шаблонов действий (ботов).
Подробнее...

Для того чтобы запустить шаблон, откройте нужную программу. Нажмите кнопку «Добавить», и выберите файл проекта, который хотите запустить.
Подробнее о том, где и как выполняется проект.

Последнее редактирование:

doc

Client
Регистрация
30.03.2012
Сообщения
8 605
Благодарностей
4 595
Баллы
113

DenisK

Client
Регистрация
28.06.2016
Сообщения
591
Благодарностей
288
Баллы
63
Автор, я тебе по IP вычислю :D.

Вроде не сложно, кроме кода конечно =) А где применять такое можно?
 
  • Спасибо
Реакции: Serkser

Sergodjan

Administrator
Команда форума
Регистрация
05.09.2012
Сообщения
19 365
Благодарностей
8 648
Баллы
113
офигенная статья, в очередной раз буду голосовать за автора..
 

doc

Client
Регистрация
30.03.2012
Сообщения
8 605
Благодарностей
4 595
Баллы
113
как на счёт продолжения статьи на примере взаимодействия с каким-нибудь чатиком в вебе, который по tcp устроен, желательно еще и через прокси, если возможно?)
 

25region

Client
Регистрация
26.09.2013
Сообщения
182
Благодарностей
57
Баллы
28

Обращаем Ваше внимание на то, что данный пользователь заблокирован.
Не рекомендуем проводить с 25region какие-либо сделки.

даже не предполагал что зп так умеет, спасибо за статью
 
  • Спасибо
Реакции: Serkser

lzlmrf

Client
Регистрация
14.08.2015
Сообщения
487
Благодарностей
148
Баллы
43
ни че не понял)
 
  • Спасибо
Реакции: zennoX

Geograph

Client
Регистрация
16.02.2014
Сообщения
209
Благодарностей
113
Баллы
43
Круто теперь каптчи можно с телефона гадать :-)
Какие еще применения можно этому найти? Отправлять статистику о работе шаблона на телефон?
Спасибо за либу Interop.NATUPNPLib - не знал про такую, может пригодиться в обычных C# приложениях
 
Последнее редактирование модератором:
  • Спасибо
Реакции: Serkser

vovain

Client
Регистрация
31.07.2015
Сообщения
183
Благодарностей
2
Баллы
18
Interop.NATUPNPLib где?
 

25region

Client
Регистрация
26.09.2013
Сообщения
182
Благодарностей
57
Баллы
28

Обращаем Ваше внимание на то, что данный пользователь заблокирован.
Не рекомендуем проводить с 25region какие-либо сделки.

Круто теперь каптчи можно с телефона гадать :-)
Какие еще применения можно этому найти? Отправлять статистику о работе шаблона на телефон?
Спасибо за либу Interop.NATUPNPLib - не знал про такую, может пригодиться в обычных C# приложениях
чат ботов пилить в терии взаимодействовать с приложениями на телефоне или на виртуалках запущеных актуально для вацапа очень, и инсты и прочей юлы))) аля зенодроид многопоточный я както так понял сей посыл )))
 
Последнее редактирование модератором:
  • Спасибо
Реакции: Serkser

amyboose

Client
Регистрация
21.04.2016
Сообщения
2 312
Благодарностей
1 190
Баллы
113
Сразу выражая недовольство некоторыми пунктами реализации:
1)
Код:
new Thread(()=> socket = listener.AcceptSocket()).Start();
Зачем поднимать целый поток ради слушателя? Есть пул потоков, а также async/await
2)
Код:
byte[] bytes = Encoding.GetEncoding(1251).GetBytes(text);
            socket.Send(bytes);
Байты можно сжать с помощью qzip/deflate стримов
Если для автора это первый опыт работы с сервером-клиентом, то тут простительно.
 
  • Спасибо
Реакции: Lord_Alfred

Serkser

Client
Регистрация
26.01.2015
Сообщения
90
Благодарностей
343
Баллы
53
Сразу выражая недовольство некоторыми пунктами реализации:
1)
Код:
new Thread(()=> socket = listener.AcceptSocket()).Start();
Зачем поднимать целый поток ради слушателя? Есть пул потоков, а также async/await
2)
Код:
byte[] bytes = Encoding.GetEncoding(1251).GetBytes(text);
            socket.Send(bytes);
Байты можно сжать с помощью qzip/deflate стримов
Если для автора это первый опыт работы с сервером-клиентом, то тут простительно.
Спасибо за замечания)
Поскольку данных передавал немного то насчет компрессии не стал заморачиваться. А с ассинхронностью я бы с удовольствием, но чего то при ее использовании PM отваливался часто, поэтому сделал на треде
 

Geograph

Client
Регистрация
16.02.2014
Сообщения
209
Благодарностей
113
Баллы
43

Serkser

Client
Регистрация
26.01.2015
Сообщения
90
Благодарностей
343
Баллы
53
Автор, я тебе по IP вычислю :D.

Вроде не сложно, кроме кода конечно =) А где применять такое можно?
Все зависит от твоей фантазии, ты можешь установить ZP на 100 серверов, а на своем пк написать шаблон, который будет отправлять команды с поручениями каждому твоему шаблону на сервере, а потом если тебе нужно срочно куда то идти, ты сможешь взять телефон и продолжишь управлять проектами даже по низкому интернет соединению)
 
  • Спасибо
Реакции: KitKat21

Serkser

Client
Регистрация
26.01.2015
Сообщения
90
Благодарностей
343
Баллы
53
как на счёт продолжения статьи на примере взаимодействия с каким-нибудь чатиком в вебе, который по tcp устроен, желательно еще и через прокси, если возможно?)
Возможно абсолютно все, главное желание, постараюсь написать после конкурса статью про сниффинг и реверсинг TCP протоколов, но сейчас пока времени не особо =)
 

Sanekk

Client
Регистрация
24.06.2016
Сообщения
987
Благодарностей
388
Баллы
63
искренне верю, что кому то это откроет новый взгляд на построение своих проектов и поможет реализовать крутые идеи!
Статья просто супер, и ведь правда это может очень помочь в реализации разных идей и управлении своими проектами!!!
ТС буду голосовать за вашу статью,как и на прошлом конкурсе
 
  • Спасибо
Реакции: Serkser

Lord_Alfred

Client
Регистрация
09.10.2015
Сообщения
3 916
Благодарностей
3 852
Баллы
113
Интересная статья! Но нужно подумать как лучше всего развить эту идею для реализации чего-то своего, т.к. банальные штуки вроде "управления зенкой с мобилки", "решение капчи на мобилке" - вряд ли кому-то нужны.

Тут лучше, пожалуй, задуматься о том, что с помощью Interop.NATUPNPLib можно сделать свой ботнет/супер-проксификатор. Т.е. сделать сервером не зенку, а свою приложеньку, которую эксплоитить по-чёрному на другие машины, в этой приложеньке делать отстук на определенный сервер, чтобы показать что эта нода готова принимать команды, а потом с зенки стучаться по всем нодам и юзать всё это добро как огромный проксификатор.
 
  • Спасибо
Реакции: Serkser

Roman*

Client
Регистрация
25.09.2013
Сообщения
1 649
Благодарностей
652
Баллы
113
Статье нужно найти более лучшее применение, чем гадание капчи. Или мне кажется или просто пока не все понятно, но не проще отснифать приложение и работать с автоматизированным процессом на автомате. Может быть с какими то зашифрованными приложениями ваше решение более подходящее.
 

Serkser

Client
Регистрация
26.01.2015
Сообщения
90
Благодарностей
343
Баллы
53
Каждый может использовать информацию из статьи как ему угодно, я рассматривал самый простой вариант дабы было нагляднее =)
 
  • Спасибо
Реакции: SHoro

desided

Client
Регистрация
19.10.2015
Сообщения
120
Благодарностей
11
Баллы
18
огромное спасибо за статью, техническая часть очень полезна!
 
  • Спасибо
Реакции: Serkser

Nick

Client
Регистрация
22.07.2014
Сообщения
1 961
Благодарностей
796
Баллы
113
Это решение очень актуально, если делать из проекта веб-сервис. Тогда на Зенке будет бэк-энд (сервер, который делает всю работу), а где-то на хостинге - просто веб-морда, которая транслирует в Зенку запросы пользователей. Без этого решения веб-морде оставалось бы только ожидать, пока Зенка сама её дёрнет и спросит, чё как — а тут фронтенд может сам к бэкенду обращаться, всё как надо. Полезная вещь! Так, чё-то я расщедрился на похвалы, а я ж конкурент в этом конкурсе))
 

ZHAG

Client
Регистрация
01.05.2014
Сообщения
228
Благодарностей
220
Баллы
43

lzlmrf

Client
Регистрация
14.08.2015
Сообщения
487
Благодарностей
148
Баллы
43
получается так можно скрыть работу шаба от снифера?
 
  • Спасибо
Реакции: Serkser

Serkser

Client
Регистрация
26.01.2015
Сообщения
90
Благодарностей
343
Баллы
53
  • Спасибо
Реакции: Dimionix

Serkser

Client
Регистрация
26.01.2015
Сообщения
90
Благодарностей
343
Баллы
53
Это решение очень актуально, если делать из проекта веб-сервис. Тогда на Зенке будет бэк-энд (сервер, который делает всю работу), а где-то на хостинге - просто веб-морда, которая транслирует в Зенку запросы пользователей. Без этого решения веб-морде оставалось бы только ожидать, пока Зенка сама её дёрнет и спросит, чё как — а тут фронтенд может сам к бэкенду обращаться, всё как надо. Полезная вещь! Так, чё-то я расщедрился на похвалы, а я ж конкурент в этом конкурсе))
Плюс еще можно в сокет сливать весь видеопоток происходящего и смотреть прямую трансляцию того что делает шаблон)))
 

BAZAg

Client
Регистрация
08.11.2015
Сообщения
1 758
Благодарностей
2 392
Баллы
113
Плюс еще можно в сокет сливать весь видеопоток происходящего и смотреть прямую трансляцию того что делает шаблон)))
Можете показать пример каким образом записывать этот же видеопоток происходящего в файл?
 

Serkser

Client
Регистрация
26.01.2015
Сообщения
90
Благодарностей
343
Баллы
53
Можете показать пример каким образом записывать этот же видеопоток происходящего в файл?
На самом деле изнутри это будет выглядеть как множество скриншотов, делаемых каждую милисекунду и вписываемых во фреймы видеопотока
 
  • Спасибо
Реакции: BAZAg

Ak2web

Новичок
Регистрация
09.07.2017
Сообщения
1
Благодарностей
0
Баллы
1
можно-же все это сделать через api телеграм?
 
A

Alelsey1611

Guest
Регистрация
16.04.2016
Сообщения
8
Благодарностей
0
Баллы
1
Ссылки на скачивание с Я.Диска не активны. Автор, можете новые ссылки написать?
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)