Delphi 当IdTCPClient.IOHandler.ReadStream()时,连接正常关闭!
我是德尔福的新手,这是我的第一个项目。 下面是一些代码:Delphi 当IdTCPClient.IOHandler.ReadStream()时,连接正常关闭!,delphi,Delphi,我是德尔福的新手,这是我的第一个项目。 下面是一些代码: procedure TForm1.Button2Click(Sender: TObject); responseStringFromServer:TStringStream; begin try if IdTCPClient1.Connected then begin dataSentToDevice:= 'http/1.0 content-length: 344 content-type: text/xml <
procedure TForm1.Button2Click(Sender: TObject);
responseStringFromServer:TStringStream;
begin
try
if IdTCPClient1.Connected then
begin
dataSentToDevice:= 'http/1.0 content-length: 344 content-type: text/xml <?xml version="1.0" encoding="UTF-8" ?> ...'
IdTCPClient1.IOHandler.WriteLn(dataSentToDevice);
responseStringFromServer := TStringStream.Create;
IdTCPClient1.IOHandler.ReadStream(responseStringFromServer);
...
然后等待设备完成处理,出现异常:“连接正常关闭”。所以我无法读取设备应该发送给我的数据。设备未关闭。我读过其他帖子,我知道设备本身会断开连接
我有一个与之通信的演示程序,它运行良好。我需要在它断开连接之前获取响应xml
另外,请求是http,我使用的是IdTCPClient(我需要使用xml请求,我不知道如何使用TidHTTP)。
可能是在设备发送响应后,它会断开连接,以便我的tcpclient在接收数据之前获得连接断开标志
任何帮助都将不胜感激
另外,请求是http,我是
使用IdTCPClient(我需要使用xml
请求,我不知道怎么做
使用tid(http)
使用IdHTTP很简单
按照调用ReadStream()的方式,它会将前4个字节(如果TIdIOHandler.LargeStream属性为True,则为8个字节)解释为按网络字节顺序指定数据长度的整数(或Int64),然后它会尝试读取这么多字节。设备是否真的发送了这样的长度值?如果没有,则ReadStream()将尝试读取错误的字节数。EIdConnClosedGracefully异常表示设备正在关闭其一端的套接字。因此,要么设备在发送数据后立即关闭连接,要么它在等待您发送下一个命令时超时,这是您无法执行的,因为您在等待上一个命令的错误数据时被阻止。如@Remy Lebeau和文档所述(编辑插入符号位于ReadStream语句上方时按F1): AByteCount表示从IOHandler读入AStream的字节数。当AByteCount包含-1且AReadUntilDisconnect包含False时,字节计数将作为整数值从IOHandler读入。AStream的大小将调整为与IOHandler预期的大小相匹配 当您连接到服务器时,如果您按照INDY客户端的预期发送字节通信,这将非常有用。服务器的一端也是以INDY WriteStream编写的,另一端是以ReadStream编写的,或者任何其他语言编写的 如果您正在从设备读取数据,请确保设备将该信息发送到流前面,或者更改您读取数据的方式。如果您知道流的大小,只需传递第二个参数:AByteCount。如果设备将在流结束时关闭通道,则传递-1作为第二个参数,传递True作为第三个参数:AReadUntil断开 如果设备发送长度未知但使用已知终止符(如CR/LF)的文本,最好使用IOHandler的ReadLn方法来获取该字符串
如果两者都不符合您的需要,请查看TIOHandlerClass和RTFM各自的Read*方法,以找到正确的方法来获取设备发送的数据。如果有运行良好的演示程序,我会使用网络嗅探器(WireShark)查看它的功能,然后将通信流与Delphi应用程序进行比较。也可以使用类似Don的代理的HTTP代理-可能比网络嗅探更简单。同意。如果您没有设备实际协议的文档,则数据包嗅探器是次佳选择。UTF-8不是有效的ContentEncoding属性值。您是改为考虑CharSet属性。此外,没有Request.Stream属性。您可以在其ASource参数中将输入流直接传递给Post()(要使用GET请求发送输入数据,必须直接调用DoRequest())。此外,我建议使用TMemoryStream而不是TStringStream,因为TStringStream在D2009中更改为支持Unicode,您不希望它意外地弄乱XML数据。好的,使用idhttp发送数据效果很好。但我仍然无法使用idhttp.get()过程从设备检索数据。现在它停止在idhttp.get()处并等待一段时间。然后它抛出EidConnConClosedGracefully异常。是否有更好的方法来请求数据,或者idhttp.get()是如何工作的。目前我正在使用IdHTTP1.get('));response是TMemoryStream的类型。有没有办法指定它应该停止等待响应的返回时间?好的,事实证明,我必须侦听另一个端口。不是我正在向其发送数据的端口。但它仍然无法正常工作:现在当我调用idhttp.get()时然后,它会一直保持在那里,直到超时发生。我必须在发送数据之前开始侦听端口,还是在发送数据之后立即开始侦听端口就足够了?
IdTCPClient1.IOHandler.ReadStream(responseStringFromServer);