如果Android中的HttpGet *** 作持续时间过长,如何避免出现错误10053(WSAECONNABORTED)?

如果Android中的HttpGet *** 作持续时间过长,如何避免出现错误10053(WSAECONNABORTED)?,第1张

概述我有一个使用Indy10TIdHttpServer(与Delphi2006一起提供)与Delphi2006Web服务应用程序进行通信的Android应用程序.Delphi应用程序生成一个大的XML文件并提供服务.XML生成可能会持续5分钟以上.如果GenerateXml()的持续时间超过大约5分钟(*),如果在DelphiIDE中运行,我将在TI

我有一个使用Indy 10 TIDhttpServer(与Delphi 2006一起提供)与Delphi 2006 Web服务应用程序进行通信的Android应用程序. Delphi应用程序生成一个大的XML文件并提供服务. XML生成可能会持续5分钟以上.

如果GenerateXml()的持续时间超过大约5分钟(*),如果在Delphi IDE中运行,我将在TIDhttpResponseInfo.WriteContent中检测到错误10053:

@H_301_7@Socket Error # 10053 Software caused connection abort.

但是,在androID方面,什么也没有检测到,并且httpGet调用将永远持续下去.

我的问题是:

1.)为什么会出现错误10053,如何避免该错误?似乎androID超时了,但http.socket.timeout设置为infinite.

2.)我该怎么做才能在客户端检测到此类错误(除了设置超时,超时必须太大才能使用)?我可以在TIDhttpServer.OnException中做些什么吗?

这是我的代码.
AndroID-下载功能,可在AsyncTask中运行:

@H_301_7@protected static httpentity downloadEntity(String url) throws IOException {    httpClIEnt clIEnt = new DefaulthttpClIEnt();      //Check because of Error 10053: but timeout is null -> infinite    Log.d("TAG", "http.socket.timeout: " + clIEnt.getParams().getParameter("http.socket.timeout"));    httpGet get = new httpGet(url);    httpResponse response;    try {        //in case of Error 10053 the following call seems to last forever (in PlainSocketImpl.read)        response = clIEnt.execute(get);    } catch (ClIEntProtocolException e) {        //...    }    //...    return response.getEntity();  }   

TIDhttpServer.OnCommandGet的Delphi实现:

@H_301_7@procedure ServeXmlDoc(XmlDoc: IXMLdocument; ResponseInfo: TIDhttpResponseInfo);var    TempStream: TMemoryStream;begin    ResponseInfo.ContentType := 'text/xml';    TempStream := TMemoryStream.Create;    XMLDoc.SavetoStream(TempStream);    ResponseInfo.FreeContentStream := True;     ResponseInfo.ContentStream := TempStream;end;procedure TMyService.httpServerCommandGet(AContext: TIDContext; RequestInfo: TIDhttpRequestInfo;  ResponseInfo: TIDhttpResponseInfo);begin    Coinitialize(nil);     try        //...        ServeXmlDoc(GenerateXml(), ResponseInfo);    finally        CoUninitialize;    end;end;

编辑:(*)即使整个过程持续时间不到2分钟,我也进行了进一步的测试并遇到了错误.

解决方法:

闲置时间过长后,AndroID和服务器之间的某些内容(例如防火墙/路由器)可能会切断连接.您应该尝试启用TCP保持活动以避免这种情况.

另一方面,这种情况是http 1.1的chunked transfer encoding设计用来处理的(假设您首先使用http 1.1).您不必等待5分钟才能完整生成完整的XML,然后再将其发送给客户端,而应该在生成XML的过程中将其分段发送.这不仅使连接保持活动状态,而且还减少了服务器的内存占用量,因为它不必一次将整个XML存储在内存中.

TIDhttpServer本身还不支持发送分块的响应(但TIDhttp确实支持接收分块的响应),但是手动实现并不是很困难.编写一个自定义的TStream派生类并覆盖其虚拟Write()方法(或使用Indy的TIDEventStream类)以使用RFC 2616 Section 3.6.1中概述的格式将数据写入http客户端.这样,您可以让ServeXmlDoc()设置ResponseInfo.TransferEnCoding属性设置为“分块”并调用ResponseInfo.Writeheader()方法,而不设置ResponseInfo.ContentText或ResponseInfo.ContentStream属性,然后将自定义流传递给IXMLdocument.SavetoStream(),这样它将在标头之后完成写响应数据.例如:

@H_301_7@type  TMyChunkedStream = class(TStream)  private    fIO: TIdioHandler;  public    constructor Create(AIO: TIdioHandler);    function Write(const Buffer; Count: Longint): Longint; overrIDe;    procedure Finished;    ...  end;constructor TMyChunkedStream.Create(AIO: TIdioHandler);begin  inherited Create;  fIO := AIO;end;function TMyChunkedStream.Write(const Buffer; Count: Longint): Longint; overrIDe;begin  if Count > 0 then  begin    fIO.WriteLn(IntToHex(Count, 1));    fIO.Write(RawToBytes(Buffer, Count));    fIO.WriteLn;  end;  Result := Count;end;procedure TMyChunkedStream.Finished;begin  fIO.WriteLn('0');  fIO.WriteLn;end;
@H_301_7@procedure ServeXmlDoc(XmlDoc: IXMLdocument; ResponseInfo: TIDhttpResponseInfo);var  TempStream: TMyChunkedStream;begin  ResponseInfo.ContentType := 'text/xml';  ResponseInfo.TransferEnCoding := 'chunked';  ResponseInfo.Writeheader;  TempStream := TMyChunkedStream.Create(ResponseInfo.Connection.IOHandler);  try    XMLDoc.SavetoStream(TempStream);    TempStream.Finished;  finally    TempStream.Free;  end;end;

另一方面,如果等待的大部分时间在GenerateXml()内部而不在XmlDoc.SavetoStream()中,那么您需要重新考虑服务器设计,并找出加速GenerateXml()的方法,或者摆脱IXMLdocument并手动创建XML,以便在创建XML内容时可以使用ResponseInfo.Connection.IOHandler将其发送.

总结

以上是内存溢出为你收集整理的如果Android中的HttpGet *** 作持续时间过长,如何避免出现错误10053(WSAECONNABORTED)?全部内容,希望文章能够帮你解决如果Android中的HttpGet *** 作持续时间过长,如何避免出现错误10053(WSAECONNABORTED)?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/web/1076148.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存