当IdTCPClient.IOHandler.ReadStream()时,连接正常关闭!

时间:2010-11-18 15:47:19

标签: 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 <?xml          version="1.0" encoding="UTF-8" ?> ...'
   IdTCPClient1.IOHandler.WriteLn(dataSentToDevice);
   responseStringFromServer := TStringStream.Create;
    IdTCPClient1.IOHandler.ReadStream(responseStringFromServer);
    ...

我有一台设备连接到本地网络。我设法成功连接到它。发送命令也有效,但是当我这样做时

IdTCPClient1.IOHandler.ReadStream(responseStringFromServer);

然后等待设备完成处理并发生异常:“连接正常关闭”。所以我无法读取设备应该发送给我的数据。设备未关闭。我已阅读其他帖子,我了解设备本身会断开连接。

我有一个与之通信的演示程序,它运行正常。我需要在它断开连接之前得到响应xml。

此外请求是http,我正在使用IdTCPClient(我需要使用xml请求,我不知道如何使用TidHTTP)。 可能是在设备发送响应之后它会丢弃连接,以便我的tcpclient在接收数据之前获得连接丢弃标记。

任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:2)

您调用ReadStream()的方式,它会将前4个字节(或者如果TIdIOHandler.LargeStream属性为True,则为8个字节)解释为网络字节顺序的整数(或Int64),指定长度数据,然后它会尝试读取那么多字节。设备实际上是否发送了这样的长度值?如果没有,那么ReadStream()将尝试读取错误的字节数。 EIdConnClosedGracefully异常表示设备正在关闭套接字。因此,设备在发送数据后立即关闭连接,或者超时等待您发送下一个命令,由于您被阻止等待上一个命令中的错误数据,因此无法执行此操作。

答案 1 :(得分:1)

  

请求也是http,我是   使用IdTCPClient(我需要使用xml   请求,我不知道该怎么做   与TidHTTP)。

使用IdHTTP很简单......

  1. 在表单上删除它的一个实例, 选择它。
  2. 在对象检查器中,转到 ProtocolVersion属性,并设置它 到pv1_0,然后打开它的
  3. 请求属性集,然后设置 Request.ContentType到text / xml,和 Request.ContentEncoding为UTF-8, 并设置其他属性if 必需的。
  4. 在表单中添加一个按钮 双击它。
  5. 在您的代码中,创建一个实例 TStringStream,并加载您的XML 内容融入其中。
  6. 将您的信息流分配给 IdHttp.Request.Source。
  7. 通过给出调用IdHttp.Get()方法 这是一个主持人地址。
  8. IdHttp.Get()返回一个字符串 是服务器发送给您的响应。

答案 2 :(得分:0)

如@Remy Lebeau和文档所述(当您的编辑插入符号超过ReadStream句子时按F1键):

  

AByteCount表示从IOHandler读取到AStream的字节数。当AByteCount包含-1且AReadUntilDisconnect包含False时,字节计数将从IOHandler 读取为Integer值。调整AStream的大小以匹配IOHandler预期的大小。

当您连接到一端写入INDY WriteStream的服务器,另一端使用ReadStream,或者如果您按照INDY客户端的预期发送该字节时,使用任何其他语言时,这非常有用。

如果您正在使用设备进行阅读,请确保设备在流前面发送该信息或更改您读取数据的方式。如果您知道流的大小,只需传递第二个参数:AByteCount。如果设备在流结束时关闭通道,则将-1作为第二个参数传递,将True作为第三个参数:AReadUntilDisconnect。

如果设备发送未知长度的文本但使用已知的终结符(如CR / LF),最好使用IOHandler的ReadLn方法来获取该字符串。

看看是否满足您的需求,看一下TIOHandlerClass的Read *方法和 RTFM ,找到正确的方法来获取设备发送的数据< / em>的