Advertisement
Serginio

Untitled

Sep 28th, 2016
5,719
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.30 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.IO.Compression;
  6. using System.IO;
  7. using System.Net.Sockets;
  8. using System.Threading.Tasks;
  9. namespace TCPConnectTo1C
  10. {
  11.  
  12.  
  13.     // Структура сообщения полученная от клиентиа
  14.     public class СтруктураСообщения
  15.     {
  16.         public bool ЕстьОтвет;
  17.         public string Команда;
  18.         public string Данные;
  19.  
  20.         public СтруктураСообщения(string Команда, string Данные, bool ЕстьОтвет)
  21.         {
  22.  
  23.             this.ЕстьОтвет = ЕстьОтвет;
  24.             this.Команда = Команда;
  25.             this.Данные = Данные;
  26.  
  27.         }
  28.  
  29.        
  30.  
  31.         public override string ToString()
  32.         {
  33.             return $"ЕстьОтвет={ЕстьОтвет}, Команда={Команда}, Данные={Данные}";
  34.         }
  35.  
  36.     }
  37.  
  38.     // Класс для формирования сообщения и его разбора
  39.     // Данные упаковываются  GZip и если сжатые данные меньше оригинала то отправляются сжатые данные
  40.     //
  41.     public class  ДляОбменаПоТСП
  42.     {
  43.         public static readonly Encoding CurrentEncoder;//=Encoding.GetEncoding(1251);
  44.  
  45.         static ДляОбменаПоТСП()
  46.         {
  47.  
  48.             //Вот здесо особенность .Net Core
  49.             // Нужно зарегистрировать провайдера
  50.             // и прописать в зависимости "System.Text.Encoding.CodePages"
  51.             Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
  52.            // CurrentEncoder = Encoding.GetEncoding("windows-1251");
  53.            // Так как мы используем Руслиш то используем кодировку 1251
  54.              CurrentEncoder = Encoding.GetEncoding(1251);
  55.  
  56.         }
  57.  
  58.  
  59.        
  60.         public static  byte[] РасжатьДанные(byte[] массивДанныхДляКоманды)
  61.         {
  62.             var memStream = new MemoryStream(массивДанныхДляКоманды);
  63.             var DecompressStream = new MemoryStream();
  64.             using (GZipStream gzipStream = new GZipStream(memStream, CompressionMode.Decompress, false))
  65.             {
  66.  
  67.                 Byte[] buffer = new Byte[1 << 16];
  68.                 int h;
  69.                 while ((h = gzipStream.Read(buffer, 0, buffer.Length)) > 0)
  70.                 {
  71.                     DecompressStream.Write(buffer, 0, h);
  72.                 }
  73.             }
  74.             return DecompressStream.ToArray();
  75.         }
  76.  
  77.         //
  78.         public static byte[] СжатьДанные(byte[] Value)
  79.         {
  80.             var memStream = new MemoryStream();
  81.             memStream.Position = 0;
  82.             using (GZipStream gzipStream = new GZipStream(memStream, CompressionMode.Compress))
  83.             {
  84.                 gzipStream.Write(Value, 0, Value.Length);
  85.                 gzipStream.Flush();
  86.             }
  87.             return memStream.ToArray();
  88.  
  89.        
  90.         }
  91.  
  92.         // Классичекое чтение из NetworkStream зная размер получаемых данных
  93.         private static byte[] МассивБайтовИзСтрима(NetworkStream стрим, int размерМассива)
  94.         {
  95.             byte[] result = new byte[размерМассива];
  96.             int количествоСчитанныхСимволов = 0;
  97.             while (размерМассива > количествоСчитанныхСимволов)
  98.             {
  99.                 количествоСчитанныхСимволов += стрим.Read(result, количествоСчитанныхСимволов, размерМассива - количествоСчитанныхСимволов);
  100.             }
  101.  
  102.             return result;
  103.         }
  104.  
  105.         public static void ЗаписатьМассивБайтовВСтрим(NetworkStream стрим, byte[] Массив)
  106.         {
  107.  
  108.             стрим.Write(Массив, 0, Массив.Length);
  109.         }
  110.  
  111.  
  112.         // Считываем из потока 1 байт и конвертируем в bool
  113.         public static bool ReadBool(NetworkStream стрим)
  114.         {
  115.             return BitConverter.ToBoolean(МассивБайтовИзСтрима(стрим,1), 0);
  116.         }
  117.  
  118.         // Конвертирум bool в 1 байт и записываем в поток
  119.         public static void Write(NetworkStream стрим, bool Value)
  120.         {
  121.             ЗаписатьМассивБайтовВСтрим(стрим, BitConverter.GetBytes(Value));
  122.        
  123.         }
  124.  
  125.         // Считываем из потока 4 байта и конвертируем в int
  126.         public static Int32 ReadInt32(NetworkStream стрим)
  127.         {
  128.             return BitConverter.ToInt32(МассивБайтовИзСтрима(стрим,4), 0);
  129.         }
  130.  
  131.         // Конвертирум int в 4 байта и записываем в поток
  132.         public static void Write(NetworkStream стрим, Int32 Value)
  133.         {
  134.             ЗаписатьМассивБайтовВСтрим(стрим, BitConverter.GetBytes(Value));
  135.  
  136.         }
  137.  
  138.         // Считываем строку. Сначала идет размер данных int
  139.         //затем считываем данные и получаем строку используя кодировку 1251
  140.         public static string ReadString(NetworkStream стрим)
  141.         {
  142.          int РазмерДанных=ReadInt32(стрим);
  143.          if (РазмерДанных == 0) return "";
  144.  
  145.          return CurrentEncoder.GetString(МассивБайтовИзСтрима(стрим,РазмерДанных));
  146.         }
  147.  
  148.         // Записываем строку. Сначала записываем размер строки, затем конвертируем в byte[] используя кодировку 1251
  149.         public static void Write(NetworkStream стрим, string Value)
  150.         {
  151.             if (Value.Length == 0)
  152.             {
  153.                 Write(стрим, 0);
  154.                 return;
  155.             }
  156.             byte[] result = CurrentEncoder.GetBytes(Value);
  157.             Write(стрим, result.Length);
  158.             ЗаписатьМассивБайтовВСтрим(стрим,result);
  159.  
  160.         }
  161.  
  162.         // Смотри WriteCompressedString это обратная операция
  163.         public static string ReadCompressedString(NetworkStream стрим)
  164.         {
  165.           //  int РазмерДанных = ReadInt32(стрим);
  166.            // return CurrentEncoder.GetString(МассивБайтовИзСтрима(стрим, РазмерДанных));
  167.             bool ЭтоСжатаяСтрока = ReadBool(стрим);
  168.  
  169.             if (!ЭтоСжатаяСтрока) return ReadString(стрим);
  170.  
  171.             int РазмерДанныхДляКоманды = BitConverter.ToInt32(МассивБайтовИзСтрима(стрим, 4), 0);
  172.             byte[] массивДанныхДляКоманды = МассивБайтовИзСтрима(стрим, РазмерДанныхДляКоманды);
  173.             массивДанныхДляКоманды = РасжатьДанные(массивДанныхДляКоманды);
  174.             return CurrentEncoder.GetString(массивДанныхДляКоманды);
  175.  
  176.         }
  177.  
  178.  
  179.         // Пытаемся сжать строку GZIP. Если размер сжатых данных меньше оригинала то записываем сжатые танные
  180.         //иначе оригинал
  181.         // Записываем данные в следующей последовательности
  182.         //bool флаг сжатия данных
  183.         //int размер данных
  184.         //byte[] данные
  185.         public static void WriteCompressedString(NetworkStream стрим, string Value)
  186.         {
  187.             if (Value.Length == 0)
  188.             {
  189.                 Write(стрим, false);
  190.                 Write(стрим, 0);
  191.                 return;
  192.             }
  193.  
  194.  
  195.             byte[] result = CurrentEncoder.GetBytes(Value);
  196.             var СжатыеДанные=СжатьДанные(result);
  197.             if (result.Length>СжатыеДанные.Length)
  198.             {
  199.             Write(стрим, true);
  200.             Write(стрим, СжатыеДанные.Length);
  201.             ЗаписатьМассивБайтовВСтрим(стрим,СжатыеДанные);
  202.             }
  203.             else
  204.             {
  205.             Write(стрим, false);
  206.             Write(стрим, result.Length);
  207.             ЗаписатьМассивБайтовВСтрим(стрим,result);
  208.             }
  209.            
  210.  
  211.         }
  212.  
  213.         // Отправляем данные на сервер
  214.         // string Команда имя метода который будет обрабатывать данные
  215.         // string ДанныеДляКоманды это сериализованные данные ввиде строки
  216.         // bool ЕстьОтвет признак функции или процедуры метода обрабатывающего данные
  217.         public static void ОтправитьКоманду(NetworkStream strim,string Команда, string ДанныеДляКоманды, bool ЕстьОтвет)
  218.         {
  219.            Write(strim,ЕстьОтвет);
  220.            Write(strim,Команда);
  221.            WriteCompressedString(strim,ДанныеДляКоманды);
  222.         }
  223.  
  224.  
  225.         // Прочитать данные с клиента
  226.         public static СтруктураСообщения ПринятьКоманду(NetworkStream strim)
  227.         {
  228.            bool ЕстьОтвет=ReadBool(strim);
  229.            string Команда=ReadString(strim);
  230.            string ДанныеДляКоманды=ReadCompressedString(strim);
  231.            return new СтруктураСообщения(Команда, ДанныеДляКоманды, ЕстьОтвет);
  232.         }
  233.     }
  234. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement