Инди 10 проблем с чтением и записью потоков - PullRequest
0 голосов
/ 22 ноября 2011

Я пытаюсь обмениваться данными между IdTCPServer и IdTCPClient, используя коллекцию, которую я преобразую в поток перед отправкой по сети.К сожалению, как бы я ни старался, я не могу передать поток между клиентом и сервером.Код всегда висит в строке IdTCPClient1.IOHandler.ReadStream (myStream, -1, True) .

Соответствующая часть моего кода показана ниже:

Клиентская часть

  with ClientDataModule do
  begin
    try
      try
        intStreamSize := StrToInt(IdTCPClient1.IOHandler.ReadLn); // Read stream size
        IdTCPClient1.IOHandler.ReadStream(myStream, -1, True);  // Read record stream
      finally
        ReadCollectionFromStream(TCustomer, myStream);
      end;
    except
      ShowMessage('Unable to read the record from stream');
    end;
  end;

Серверная часть

    try
      try
        SaveCollectionToStream(ACustomer, MStream);
      finally
        MStream.Seek(0, soFromBeginning);
        IOHandler.WriteLn(IntToStr(MStream.Size));   // Send stream size
        IOHandler.Write(MStream, 0);        // Send record stream
      end;
    except
      ShowMessage('Unable to save the record to stream');
    end;

Буду очень признателен за вашу помощьс решением этой проблемы.

Спасибо,

JDaniel

1 Ответ

1 голос
/ 23 ноября 2011

Вы устанавливаете для параметра AReadUntilDisconnect параметра ReadStream() значение True, что говорит о необходимости продолжать чтение до тех пор, пока соединение не будет закрыто.Вместо этого вам нужно установить для параметра значение False.Вам также нужно передать размер потока в параметре AByteCount, поскольку вы отправляете размер потока отдельно, поэтому вы должны указать ReadStream(), сколько фактически нужно прочитать.

Попробуйте это:

Клиент:

with ClientDataModule do
begin
  try
    intStreamSize := StrToInt(IdTCPClient1.IOHandler.ReadLn);
    IdTCPClient1.IOHandler.ReadStream(myStream, intStreamSize, False);
    myStream.Position := 0;
    ReadCollectionFromStream(TCustomer, myStream);
  except
    ShowMessage('Unable to read the record from stream');
  end;
end;

Сервер:

try
  SaveCollectionToStream(ACustomer, MStream);
  MStream.Position := 0;
  IOHandler.WriteLn(IntToStr(MStream.Size));
  IOHandler.Write(MStream);
except
  ShowMessage('Unable to save the record to stream');
end;

Если вы можете изменить свой протокол, тогда вы можете позволить Write() и ReadStream() внутренне обмениваться размером потока для вас., вот так:

Клиент:

with ClientDataModule do
begin
  try
    // set to True to receive a 64bit stream size
    // set to False to receive a 32bit stream stream
    IdTCPClient1.IOHandler.LargeStream := ...;

    IdTCPClient1.IOHandler.ReadStream(myStream, -1, True);
    myStream.Position := 0;
    ReadCollectionFromStream(TCustomer, myStream);
  except
    ShowMessage('Unable to read the record from stream');
  end;
end;

Сервер:

try
  SaveCollectionToStream(ACustomer, MStream);
  MStream.Position := 0;

  // set to True to send a 64bit stream size
  // set to False to send a 32bit stream stream
  IOHandler.LargeStream := ...;

  IOHandler.Write(MStream, 0, True);
except
  ShowMessage('Unable to save the record to stream');
end;
...