Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Сети > Проблема связанная с TClientSocked и TServerSocked


Автор: Ak47black 25.4.2007, 21:02
Здраствуйте.
Вообшем у меня проблема с использованием TClientSocked и TServerSocked.
Даж незнаю с чего начать, попробую объяснить поподробней(как смогу)
Проблема:
    Если отправлять большие куски данных(пакеты) и очень быстро то у меня происходит смешивание их и получаеться  ‘Каша’  smile 
    Тоесть данные приходят сразу от двоих посланий.
    Отследить немогу потомучто незнаю по сколько они обрываються и очень трудно проследить вообше.
user posted image
    Как с этим бороться  smile ?

Автор: AugMaster 25.4.2007, 22:05
"каша" имеется ввиду что они склеиваются ? или то что часть пакета теряется ? поподробнее плиз

Автор: MetalFan 26.4.2007, 10:52
а как у тебя получается послать второй кусок, недоконца отправив первый?
1) пример кода клиента
2) пример кода сервера, при котором наблюдается данная проблема

Автор: Ak47black 26.4.2007, 12:47
Незнаю может нето чтото, но скорей всего изза того что смешиваються, хотя незнаю может я и обсурд говорю
(весь немогу выложить слишком большой)

Вообшем вот мой 'велосипедный' модуль осушествляюший пересылку
Код

unit TransferParser;

interface

uses
  Base64, CryptionMod, Dialogs, SysUtils, Classes;

type
  TTransferChunk = record
    param: array of string;
  end;

function Outpacked(OutText: TTransferChunk): string;
function Inpacked(ReceivedText: string): TTransferChunk;

implementation

var
  LastNotCompleted: Boolean;
  TempTransfered: TTransferChunk;

function Inpacked(ReceivedText: string): TTransferChunk;
var
  i: Integer;
  HasStart: Boolean;
  HasEnd: Boolean;
begin
  HasStart:= False;
  HasEnd:= False;

  if pos('<',ReceivedText)<>0 then
  begin
    HasStart:= True;
    Delete(ReceivedText,1,1);
  end;

  if pos('>',ReceivedText)<>0 then
  begin
    HasEnd:= True;
    Delete(ReceivedText,Length(ReceivedText),1);
  end;

  if HasStart then SetLength(TempTransfered.param,0);

  if LastNotCompleted then
  begin
    if (pos('|',ReceivedText)<>0) then
    begin
       //Тут бывает вот эиа ошибка изза того что TempTransfered.param= nil
      begin
        TempTransfered.param[Length(TempTransfered.param)-1]:= Decode(TempTransfered.param[Length(TempTransfered.param)-1]+Copy(ReceivedText,1,pos('|',ReceivedText)-1));
        Delete(ReceivedText,1,pos('|',ReceivedText));
        LastNotCompleted:= False;
      end;
    end
    else
    begin
      TempTransfered.param[Length(TempTransfered.param)-1]:= TempTransfered.param[Length(TempTransfered.param)-1]+ReceivedText;
      ReceivedText:= '';
    end;
  end;

  while (pos('|',ReceivedText)<>0) do
  begin
    SetLength(TempTransfered.param,Length(TempTransfered.param)+1);
    TempTransfered.param[Length(TempTransfered.param)-1]:= Decode(Copy(ReceivedText,1,pos('|',ReceivedText)-1));
    Delete(ReceivedText,1,pos('|',ReceivedText));
  end;

  if (ReceivedText<>'') then
  begin
    SetLength(TempTransfered.param,Length(TempTransfered.param)+1);
    TempTransfered.param[Length(TempTransfered.param)-1]:= ReceivedText;
    ReceivedText:= '';
    LastNotCompleted:= True;
  end;

  if HasEnd then
  begin
    Result:= TempTransfered;
    SetLength(TempTransfered.param,0);
  end
    else SetLength(Result.param,0);

end;

function Outpacked(OutText: TTransferChunk): string;
var
  i: integer;
  Sendtext: String;
  s1,s2:pChar;
begin
  for i:=0 to Length(OutText.param)-1 do
  begin
    Sendtext:= Sendtext+Encode(OutText.param[i])+'|';
  end;
  Result:= '<'+Sendtext+'>';
end;


Посылаю например вот так 
Код

var
  pack: TTransferChunk;
begin
  SetLength(pack.param,6);
  pack.param[0]:= '$SearchFoundItem';
  pack.param[1]:= Location;
  pack.param[2]:= IntToStr(Size);
  pack.param[3]:= FileType;
  pack.param[4]:= ModifiedDate;
  pack.param[5]:= ComponentToString(SmallIcon);
  try
    Socket.SendText(Outpacked(pack));
  except
  end;
end;


Принимаю
Код

Inpacked(ReceiveText)


При очень быстой посылке данные очень редко но иногда неприходят корректно :(

Автор: MetalFan 26.4.2007, 16:40
ну это нормально...
проверяй функцию Outpacket... в ней есть очень нехоршая ошибка...
найдешь - молодец)
подсказка - что обычно содержат неинициализированные локальные переменные?

Автор: Ak47black 26.4.2007, 17:52
MetalFan, я наверно нашол, хотя ммм... может и нето
Я думаю 
Код

Sendtext:= '';

Надо  smile 

Автор: Ak47black 26.4.2007, 18:52
Там нетолко изза этого.
Вообшем если есть какинибудь мнения то пишите.

Автор: Ak47black 26.4.2007, 19:55
Тут что с Сокетами.
Лан проведем эксперент, я приклепляю сам пероект эксперемента   smile (исходники внутри) .
Вот кто скачает сразу увидет что тут проблема!
user posted image
Я скорей всего не туплю тут.

Автор: AugMaster 27.4.2007, 11:06
к сожалению мало времени,не могу глянуть твой экзапмл. Проверь, чтобы Socket.SendText(Outpacked(pack))=длине этого Outpacked(pack) . Если не равно - значит часть данных не высылается из-за перегрузки буфера отправки. Тогда ждешь событие OnSend(или OnWrite, чтоб я так помнил, оно есть в компоненте в Events) и доотправляешь то, что не было отправлено из-за перегрузки.

Автор: Ak47black 27.4.2007, 12:27
Цитата

OnWrite

Хм.. ,шас попробую.

Автор: Ak47black 27.4.2007, 12:59
Ну OnWrite то неработает (точнее событие происходит не после каждой посылке),но тут я тож думаю что проблема изза перегрузки.

Добавлено @ 13:03
Кто-нибудь может сказать что-нибудь по этому поводу?
Если кто непонимает в чем проблемма, в крипленом исходнике всё поймете)

Автор: Ak47black 27.4.2007, 20:01
AugMaster, 
Цитата

Socket.SendText(Outpacked(pack))=длине этого Outpacked(pack)

Помогло. +

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)