Народ, кто как соединяет пакеты после передачи?
В интернете куча примеров, но не один не работает, написал свое...
Не красиво, но код работает стабильно уже пол года.
В пакет перед отправкой добавлял маркеры, начала пакета, конца и конца строки.
После передачи, все это дело соединяю, анализируя в каком месте произошел пакета (пришлось предугадать море вариантов)
Щас интересно стало, по любому же это можно красивее организовать?
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);