Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 当IdTCPClient.IOHandler.ReadStream()时,连接正常关闭!_Delphi - Fatal编程技术网

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很简单

  • 在表单上删除它的一个实例, 选择它
  • 在对象检查器中,转到 ProtocolVersion属性,并设置它 到pv1_0,然后打开其
  • 请求属性集和 将Request.ContentType转换为text/xml,以及 将Request.ContentEncoding转换为UTF-8, 如果需要,请设置其他属性 必需的
  • 在表单中添加一个按钮,然后 双击它
  • 在代码中,创建 TStringStream,并加载您的XML 满足于它
  • 将您的流分配给 IdHttp.Request.Source
  • 通过给定 它是一个主机地址
  • Get()返回一个字符串,该字符串 是服务器发送给您的响应

  • 按照调用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);