0
votes

I've recently needed to upgrade an old Delphi 6 project to Delphi 2007. It is a server application using the Indy TidTCPServer component. I've followed all the examples I could find on upgrading to Indy 10.

The application interfaces with an old VB6 application (that we do not have the code for) via TCP/IP. I'm having a difficult time because the Execute event on the Indy component fires as soon as the VB6 application connects, but it does not write any data. This causes the application to hang waiting for the application to send data that never arrives.

The original code looked like:


data := AContext.Connection.IOHandler.ReadLn;
if data <> '' then
  begin
    // do some stuff
  end;

I've tried several code examples from the Indy examples, as well as here on StackOverlow. An example is:

AContext.Connection.IOHandler.CheckForDataOnSource(10);
if not AContext.Connection.IOHandler.InputBufferIsEmpty then
  begin
    data := AContext.Connection.IOHandler.ReadLn();
    if data <> '' then
      begin
        // do some stuff
      end;
  end;

Strangely enough, the original code works flawlessly when I hit it with a .NET client. This only seems to be a problem coming from the VB6 application.

3

3 Answers

1
votes

I believe Indy 9 came with Delphi 6 and Indy 10 does come with Delphi 2007 so the problem appears to be the differences between Indy 9 and Indy 10. Unfortunately, Indy 10 was not always backwards compatible.

Here is a brief overview of some of these changes Object Hierarchy Changes in Indy 10

The interesting part is you say the Net client connects fine...assumedly with the unmodified version of your server simply recompiled with Delphi 2007? If so then it sounds like you may have Indy 10 already installed to build your Delphi 6 system...

1
votes

Sounds like it's time for you to fire up WireShark and see what's actually being sent/received. That might give you the clue that you need.

I had an issue which caused me problems upgrading from Indy 9 to Indy 10 with C++Builder2009. The TIdTcpClient "Connect" method in Indy 9 has a declaration roughly like this

void Connect(int ConnectTimeout);

In Indy10, "ConnectTimeout" is now a property, and the Connect method now has a declaration similar to this:

void Connect(String HostName);

So my old code with "Connect(5000);" compiled fine (because there's an automatic conversion operators from Int to String) was now tried to connect to a host called "5000"....

1
votes

Problem solved. The following code works...


AContext.Connection.IOHandler.CheckForDataOnSource(10);
  if not AContext.Connection.IOHandler.InputBufferIsEmpty then
    begin
      data := AContext.Connection.IOHandler.InputBuffer.Extract;

After closely inspecting the stream (as suggested by @Roddy), I was able to determine that the VB6 application was not sending a CRLF on the connections, which was causing the AContext.Connection.IOHandler.ReadLn; to block waiting for a CRLF that never came.

Thank you @Darian and @Roddy for helping me find the answer.