Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Сети > Range Check Error


Автор: Sokolll 27.7.2007, 18:18
Использую Indy10.1.5  TIdTCPServer и TIdTCPClient, SSL  (0.96m).
Подсоединяюсь к серверу клиентом, все работает нормально. Останвливаю сервер, запускаю снова на том же порту, подсоединяюсь -
и на клиенте и на сервере вылетает ERangeError:   Range Check Error   (причем вылетает не каждый раз) - в модуле IdIOHanlder.pas в процедуре TIdIOHandler.ReadBytes в после строки ReadFromSource:
Код

    // Read from stack until we have enough data
    while FInputBuffer.Size < AByteCount do begin
      ReadFromSource(False);
      CheckForDisconnect(True, True);
    end;


На сервере читаю строки:
Код

procedure TSpServer.IdTCPServerExecute(AContext: TIdContext);
var
  S: string;
begin
  ...
   S:=AContext.Connection.IOHanlder.ReadString(8);
  ...

На клиенте(в потоке)  аналогично:
Код

procedure TSpClientReadingThread.Run;
var
  S: string
begin
  if not FConnected then
    Exit;
  IdTCPClient.IOHandler.ReadString(8);
  ...


Если делать то же самое без SSL - все нормально работает.
Искал в И-нете - нашел (http://newsgroups.cryer.info/borland/public.delphi.internet.winsock/200504/0504131867.html) , что это вроде бы как баг версии Indy 10.0.52 и в следующих версиях он исправлен.

Помогите, плиз!


Автор: MetalFan 28.7.2007, 17:50
скачай последнюю 10.1.6 версию, может там эта проблема решена

Автор: Sokolll 29.7.2007, 06:56
Цитата

скачай последнюю 10.1.6 версию, может там эта проблема решена

скачал - то же самое :(

Автор: MetalFan 29.7.2007, 15:03
найди ту строку, на которой действительно возникает исключение. выход за пределы массива...
а те куски, что приведены, ни о чем не говорят

Автор: Sokolll 29.7.2007, 22:28
Цитата

найди ту строку, на которой действительно возникает исключение. выход за пределы массива...
а те куски, что приведены, ни о чем не говорят


IDE  показывает, что ошибка происходит в IdIOHandler.pas вот здесь (строка CheckForDisconnect):
Код

procedure TIdIOHandler.ReadBytes(
  var VBuffer: TIdBytes;
  AByteCount: Integer;
  AAppend: Boolean = True);
begin
  Assert(FInputBuffer<>nil);

  if AByteCount > 0 then begin
    // Read from stack until we have enough data
    while FInputBuffer.Size < AByteCount do begin
      ReadFromSource(False);
      CheckForDisconnect(True, True);
    end;
    FInputBuffer.ExtractToBytes(VBuffer, AByteCount, AAppend);
  end else if AByteCount = -1 then begin
    ReadFromSource(False, ReadTimeout, False);
    CheckForDisconnect(True, True);
    FInputBuffer.ExtractToBytes(VBuffer, -1, AAppend);
  end;
end;


Разобрался я вроде:
Сначала на клиенте сделал обработку ошибок:
Код

procedure TSpClientReadingThread.Run;
var
  S: string;
begin
  if not FConnected then
    Exit;
  try
    S:=IdTCPClient.IOHandler.ReadString(8);
  except;
    Stop;
  end;

Ошибка все равно вылетала. Потом дошло: выполниться ли код в потоке или нет у меня зависит от FConnected, значение которого меняется на False только в обработчике IdTCPClient.OnDisconnected:
Код

procedure TSpClientReadingThread.IdTCPClientDisconnected(Sender: TObject);
begin
  FConnected:=False;
end;

Получается, что OnDisconnected не срабатывает. Добавил строчку FConnected:=False в Run и стало работать нормально:
Код

procedure TSpClientReadingThread.Run;
var
  S: string;
begin
  if not FConnected then
    Exit;
  try
    S:=IdTCPClient.IOHandler.ReadString(8);
  except;
    FConnected:=False;
    Stop;
  end;

Работает, но не могу понять, почему не работало до этого - ведь поток то останавливаю, да и почему RangeCheckError. Без SSl все ОК.

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