Discussion:
TIdTCPClient - not seeing response from server until disconnect
(too old to reply)
dave
2007-11-10 13:08:43 UTC
Permalink
Using Indy 9.0.4 with Delphi 5 ...



I'm trying write an application that sends an XML request to a shipping
server (one of the big 3 international shippers), then receive an XML
response. The code sample they sent along with their documentation was
for C#.NET. Using their C# code, I can connect, receive, and parse the
received XML with no trouble.



With Delphi 5:

I've been using Wireshark to see what's happening, and it seems that I
don't get a response back from the server until I disconnect the socket
completely, which by that time, I can't read from the socket anymore.
I've tried many different methods of sending/receiving, to no avail.
The current code I'm using is something I found of Remy's (much respect
for all the time you guys put into this project).



Data := CHECKSERVERRESPONSE; //constant containing XML request text

with Client do

begin



Connect;

try

OpenWriteBuffer;

try

Write(Data);

except

CancelWriteBuffer;

raise;

end;

CloseWriteBuffer;

Sleep(2000);

Application.ProcessMessages;

Resp := ReadString(ReadInteger);

ShowMessage(Resp);

finally

Disconnect;

end;

end;

I can trace it through the WS2Call function in IdWinSock2, where it just
hangs.



For reference, here's the .NET code that does work. The big difference
that I see (and maybe I just haven't figured out how to accomplish the
same thing w/the Indy component) is that it calls a Shutdown method on
the socket, but specifically tells it to shut down the incoming
connection to the server, not completely disconnecting.



ssSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);



IPAddress hostadd = Dns.Resolve("192.168.40.106").AddressList[0];



IPEndPoint EPhost = new IPEndPoint(hostadd, 2077);



ssSocket.Connect(EPhost);



//variable 'request' constaints the request XML

ssSocket.Send(ASCIIEncoding.ASCII.GetBytes(request));



ssSocket.Shutdown(SocketShutdown.Send);



//Wait for ES Server to send response

int timeOut = 180 * 100000;



if(!ssSocket.Poll(timeOut, SelectMode.SelectRead))

{

throw new Exception("Could not read from SS service. Timed out.");

}

const int iBufferLen = 4096;

byte[] buffer = new byte[iBufferLen];



int iRead = 0;

MemoryStream stResponse = new MemoryStream();

while(0<(iRead = ssSocket.Receive(buffer)))

{

stResponse.Write(buffer, 0, iRead);

}



//Convert response to a plain string xml

string response =
ASCIIEncoding.ASCII.GetString(stResponse.GetBuffer(), 0,
(int)stResponse.Length);



richTextBox1.Text = response;



I've tried different things like using a TMemoryStream to read, using
ReadStream, tried ReadLn, ReadStrings, etc, but I've not gotten anywhere.



Any help is appreciated.



-d
d***@gmail.com
2013-11-26 09:09:55 UTC
Permalink
Post by dave
Using Indy 9.0.4 with Delphi 5 ...
I'm trying write an application that sends an XML request to a shipping
server (one of the big 3 international shippers), then receive an XML
response. The code sample they sent along with their documentation was
for C#.NET. Using their C# code, I can connect, receive, and parse the
received XML with no trouble.
I've been using Wireshark to see what's happening, and it seems that I
don't get a response back from the server until I disconnect the socket
completely, which by that time, I can't read from the socket anymore.
I've tried many different methods of sending/receiving, to no avail.
The current code I'm using is something I found of Remy's (much respect
for all the time you guys put into this project).
Data := CHECKSERVERRESPONSE; //constant containing XML request text
with Client do
begin
Connect;
try
OpenWriteBuffer;
try
Write(Data);
except
CancelWriteBuffer;
raise;
end;
CloseWriteBuffer;
Sleep(2000);
Application.ProcessMessages;
Resp := ReadString(ReadInteger);
ShowMessage(Resp);
finally
Disconnect;
end;
end;
I can trace it through the WS2Call function in IdWinSock2, where it just
hangs.
For reference, here's the .NET code that does work. The big difference
that I see (and maybe I just haven't figured out how to accomplish the
same thing w/the Indy component) is that it calls a Shutdown method on
the socket, but specifically tells it to shut down the incoming
connection to the server, not completely disconnecting.
ssSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
IPAddress hostadd = Dns.Resolve("192.168.40.106").AddressList[0];
IPEndPoint EPhost = new IPEndPoint(hostadd, 2077);
ssSocket.Connect(EPhost);
//variable 'request' constaints the request XML
ssSocket.Send(ASCIIEncoding.ASCII.GetBytes(request));
ssSocket.Shutdown(SocketShutdown.Send);
//Wait for ES Server to send response
int timeOut = 180 * 100000;
if(!ssSocket.Poll(timeOut, SelectMode.SelectRead))
{
throw new Exception("Could not read from SS service. Timed out.");
}
const int iBufferLen = 4096;
byte[] buffer = new byte[iBufferLen];
int iRead = 0;
MemoryStream stResponse = new MemoryStream();
while(0<(iRead = ssSocket.Receive(buffer)))
{
stResponse.Write(buffer, 0, iRead);
}
//Convert response to a plain string xml
string response =
ASCIIEncoding.ASCII.GetString(stResponse.GetBuffer(), 0,
(int)stResponse.Length);
richTextBox1.Text = response;
I've tried different things like using a TMemoryStream to read, using
ReadStream, tried ReadLn, ReadStrings, etc, but I've not gotten anywhere.
Any help is appreciated.
-d
I realize this is an old post, but since I just had this problem myself and spent a ridiculous amount of time trying to figure it out I'll post here what my problem was.

A TCP message is terminated by two (2) CRLN occurrences and the server will hang when reading a TCP message until it finds them. I was sending only one CRLN at the end of my message.
Loading...