Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.03.2017, 10:49   #1
aesoem
Форумчанин
 
Регистрация: 24.12.2007
Сообщений: 288
По умолчанию фрагментация пакетов serversocket

Народ, кто как соединяет пакеты после передачи?

В интернете куча примеров, но не один не работает, написал свое...
Не красиво, но код работает стабильно уже пол года.

В пакет перед отправкой добавлял маркеры, начала пакета, конца и конца строки.
После передачи, все это дело соединяю, анализируя в каком месте произошел пакета (пришлось предугадать море вариантов)

Щас интересно стало, по любому же это можно красивее организовать?

unit
Код:
unit JoinPocket;

interface
 {писать тут заголовок чтобы функция была видна в другихформах}
 function JoinStr(const S: string): string;
function CompileTXT(temp:String):String;
implementation


uses System.Classes,System.SysUtils,VCl.Forms, MainUnit, DataUnit;



{.........................................................
СОЕДИНЯЕТ ДВЕ СТРОКИ ЕСЛИ:
А)  ПРЕДЫДУЩАЯ СТРОКА ИМЕИТ МАРКЕР &
б)  СТРОКА НАЧИНАЮЩАЯСЯ С <+> ИМЕЕТМАРКЕР & В КОНЦЕ НЕЕ ЖЕ
при других условиях <+> не обрабатывает!
........................................................
}
function JoinStr(const S: string): string;
Const
MarkEndStr = '&';
var
  temp  : Tstrings;
  i : integer;
  STemp1,STemp2:String;
begin
temp:=tstringlist.Create;
temp.Text:=S;

for I := 1 to temp.Count-1 do
  if pos(#13#10'<+>',temp.Text)>0 then
  begin
   STemp1:=temp.Strings[i-1];
   STemp2:=temp.Strings[i];

   if (STemp1[length (Stemp1) ]=MarkEndStr) and (STemp2[length (Stemp2) ]=MarkEndStr) then
    temp.Strings[i]:= StringReplace( temp.Strings[i],'<+>', '', []);
  end;

result:=temp.Text;
temp.Free;
end;


{
ФУНКЦИЯ В КОТОРУЮ НУЖНО ПЕРЕДАТЬ СОБРАНЫЙ ИЗ КУСКОВ ТЕКСТ.
Данная функция соединяет строки в зависимосьти от логики
}
function CompileTXT(temp:String):String;
var
i,i2:integer;
str:String;
temp_array:tstrings;
begin
temp_array:=Tstringlist.Create;
temp_array.Text:=temp;
{максимальное значение прогрессабара}
mainform.ProgressBar2.Visible:=true;
mainform.ProgressBar2.Max:=temp_array.Count;

{УДАЛЯБ ПЕРВУЮ И И ПОСЛЕДНРЮЮ СТРОКУ - МАРКЕРЫ НАЧАЛА И КОНЦА ПАКЕТА}
     temp_array.Delete(0);
     temp_array.Delete(  temp_array.Count-1);

     temp_array.Text:= JoinStr(temp_array.Text);     //соединяю
     str:= temp_array.Text;

     for I := 1 to temp_array.Count-1 do    //
     begin
     application.ProcessMessages;
     mainform.ProgressBar2.Position:=i;
     mainform.StatusLabel.Caption:='Обработка блоков данных ('+inttostr(i) + ' из ' + inttostr(temp_array.Count) + ')' ;

     //ОСНОВНОЙ КОМПЛЕКТ ОПЕРАТОРОВ СОЕДИНЕНИЯ СТРОК
         if str[pos('<+>',temp_array.Text)-3]<>'&' then
           temp_array.Text:=StringReplace( temp_array.Text,#13#10+'<+>', '', [])
             else
         if str[pos('<+>',ReciveText.Text)+4]<>'' then
           temp_array.Text:=StringReplace( temp_array.Text,'<+>', '', [])
             else
           temp_array.Text:=StringReplace( temp_array.Text,#13#10+'<+>', '', [])   ;

     //ПОМЕЧАЮ,ЕСЛИ СТРОКА ПУСТАЯ
        for I2 := 0 to temp_array.Count-1 do
            if length (temp_array.Strings[i2])=0 then
            temp_array.Strings[i2]:='<delpck>';



     ///удаляю управляющий символы КОНЦА СТРОКИ
             str:=   temp_array.Text;
             str:=StringReplace(str, '&',               '', [rfReplaceAll]) ; //конец строки
             str:=StringReplace(str, #13#10+'<delpck>', '', [rfReplaceAll]) ; //метки пустой строки
             temp_array.Text:=str;

     end;

           // ReciveText.SaveToFile('C:\posle.txt');
result:= temp_array.Text;
temp_array.Free;
mainform.ProgressBar2.Visible:=false;
end;

end.


прием:
Код:
if temp.Strings[0]='<start' then
begin
  resive:=true;
  mainform.StatusLabel.Caption:='Получаю данные от терминала '+socket.RemoteAddress+'...';
end;

if resive then
  begin
    ReciveText.Text:= ReciveText.Text+'<+>'+temp.Text;   //добавляю куски пакета пока не придет последний с отметкой 'end>'

    if pos('end>',ReciveText.Text)>0 then
       begin
         //отключаю режим передачи блоков данных
         resive:=false;

         ReciveText.Text:= CompileTXT(ReciveText.Text); 

         ReciveText.Text   - тут собраный пакет !

         ReciveText.Clear; //подготовка к последующей загрузке списка (к 
  end;

передача
Код:

 otvet.Add('<start');  //маркер начала блока

                otvet.Add('строка Х ...'+'&');   /& - конец строки           
                otvet.Add('строка 2 ...'+'&' );            
                otvet.Add('строка Х ...' +'&' );    

otvet.Add('end>'); //маркер конца блока      
socket.SendText(otvet.Text);

Последний раз редактировалось aesoem; 01.03.2017 в 11:03.
aesoem вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Перехват пакетов Lui C/C++ Сетевое программирование 1 03.11.2011 17:57
фрагментация IP пакета... Женя_88 C/C++ Сетевое программирование 8 15.11.2010 23:57
Декодирование пакетов..!!!! Memfis1992 Работа с сетью в Delphi 9 22.06.2010 18:04
Есть ли у IdTCPServer такое свойство как у ServerSocket: ServerSocket.Socket.ActiveConnectio ns? TwiX Работа с сетью в Delphi 3 07.03.2010 14:28
Генератор пакетов Mr_Romik Работа с сетью в Delphi 3 30.10.2009 23:56