Search code examples
socketsdelphiindy

Indy 9 to Indy 10 App: Connection refused


I'm porting and old Delphi 2009 app with Indy 9 to Delphi 11 with Indy 10:

// *************** Indy Version 9:
IdTCPClient1.Host := '123.456.789.012';
IdTCPClient1.Port := 123;
IdTCPClient1.Connect;
IdTCPClient1.OpenWriteBuffer;
IdTCPClient1.Write(Data);
i :=  IdTCPClient1.ReadInteger(True);
x := IdTCPClient1.ReadLn('</root>', 20000, 1500);
// Works OK

// *************** Indy Version 10
XMLStream := TMemoryStream.Create;
XMLDoc1.XML.SaveToStream(XMLStream);
IdTCPClient1.Host := '123.456.789.012';
IdTCPClient1.Port := 123;
IdTCPClient1.Connect;
IdTCPClient1.Socket.Open;
IdTCPClient1.Socket.WriteBufferOpen;
IdTCPClient1.Socket.Write(XMLStream, XMLStream.Size);
i := IdTCPClient1.Socket.ReadInt32(True);
x := IdTCPClient1.Socket.ReadLn('</root>', 20000, 1500);
// Socket Error # 10061 Connection refused.

Both versions are executing in the same PC/User... Any help will be appreciated. Francisco

    //Still receiving Socket Error # 10061: Connection Refused
    IdTCPClient1.Host := '123.456.789.0';
    IdTCPClient1.Port := 55065;
    IdTCPClient1.Connect;
    IdTCPClient1.Socket.WriteBufferOpen;
    IdTCPClient1.Socket.Write(XMLStream, XMLStream.Size);
    i := IdTCPClient1.Socket.ReadInt32(True);
    sResp := IdTCPClient1.Socket.ReadLn('</root>', 20000, 1500);
    IdTCPClient1.Socket.WriteBufferFlush;
    IdTCPClient1.Socket.Close;
    IdTCPClient1.Disconnect;
    // I omitted some code like try, except

Solution

  • Your translation to Indy 10 is not quite correct. You should not be calling Socket.Open() at all, as Connect() already handles that internally, and that Open() call is what actually creates the socket and establishes the TCP connection. So, you are trying to open a 2nd connection, which won't work. Get rid of that call completely:

    IdTCPClient1.Connect;
    // IdTCPClient1.Socket.Open; // <-- get rid of this!
    

    Also, in both of your codes, you are opening Indy's internal write buffer, but where are you flushing/closing it? As long as the buffer is open, any writes you perform will store their bytes in the buffer only and not transmit them over the socket (unless you assign a buffer threshold value, which your example is not).

    // *************** Indy Version 9
    IdTCPClient1.Connect;
    IdTCPClient1.OpenWriteBuffer;
    IdTCPClient1.Write(Data);
    ...
    // where is the call to (Flush/Close/Cancel)WriteBuffer?
    
    // *************** Indy Version 10
    IdTCPClient1.Connect;
    IdTCPClient1.Socket.WriteBufferOpen;
    IdTCPClient1.Socket.Write(XMLStream, XMLStream.Size);
    ...
    // where is the call to WriteBuffer(Flush/Close/Cancel)?
    

    In general, you don't need to use Indy's write buffer unless you are sending LOTS of data and would benefit from the performance boost that the buffering might offer you. TCP already does a decent job of buffering data in the socket's own internal buffer by default, so you typically don't need to use Indy's write buffering on top of that, too.