3
votes

I am using a TIdTcpServer component to implement a basic server side application. I have clients witch send strings to the server,ascii encoded, ending in these to characters #@.

eg :

this_is_a_sample#@ thisis_another_sample#@

My OnExecute method is the following :

procedure TLX8511.ProcessEvent(AContext: TIdContext);
var
  recv : String;
begin
    with AContext.Connection.IOHandler do
    begin
          CheckForDataOnSource(20);
          if not InputBufferIsEmpty then
          begin
              recv := ReadLn('#@');
              WriteLn(recv);
          end;
    end;
end

However when the ReadLn is executed I receive a wierd error : Buffer terminator must be specified

What I am doing wrong ?

LE : I am using Indy with lazarus on linux so this might be some porting issue

Thank you.

1
In TIdIOHandler.ReadLn, this code LTerm := ToBytes(ATerminator, AByteEncoding {$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF} ); is setting LTerm to a zero-length array. Not sure why mind you. You have the source to Indy, so you can just debug this. You know the text of the error. You can find the single place in the code that the error is raised. You can break there and look at the call stack. And then work out why that route was taken.David Heffernan
LTerm get's nulled after the ToBytes function call. I will dig deeper.Thanksopc0de
The only way ToBytes() can return an empty byte array for a non-empty input string is if the underlying character encoding engine (which in this case is iconv) fails to encode the input characters. Indy does have a slightly buggy/incomplete iconv implementation, so it is not unheard of to run into character encoding problems such as this on non-Windows platforms. Your use of IIdTextEncoding tells me you are using a recent Indy release that shipped with Delphi XE4, so be sure that you are using an up-to-date SVN snapshot so you have all of the latest bug fixes since XE4's initial release.Remy Lebeau

1 Answers

3
votes

I don't like to answer my own questions but based of David Heffernan's suggestion I dug up the problem myself.

Turns out you must specify the encoding in order to avoid that exception so here is the solution:

procedure TLX8511.ProcessEvent(AContext: TIdContext);
var
  recv : String;
  encoding : IIdTextEncoding;
begin
    encoding := IndyTextEncoding_ASCII;
    with AContext.Connection.IOHandler do
    begin
          CheckForDataOnSource(20);
          if not InputBufferIsEmpty then
          begin
              recv := ReadLn('#@',encoding,encoding);
              WriteLn(recv);
          end;
    end;
end;