简体   繁体   English

Delphi-使用套接字从Web下载文件

[英]Delphi- downloading files from the web with sockets

I have tried Synapse, Indy and ICS and I am not satisfied with them. 我尝试过Synapse,Indy和ICS,我对它们并不满意。 I want to download multiple files in multiple parts at the same time, support resuming, gzip-encoded files, cookies, logging to websites using POST and so on. 我想同时下载多个部分的多个文件,支持恢复,gzip编码文件,cookie,使用POST登录网站等等。 So I think I will just write in with sockets. 所以我想我会用套接字写。 But I see there is a plenty of sockets available in Delphi: TTcpClient, TRawSocket, TCGIRequest, TClientSocket and so on. 但我发现Delphi中有很多套接字:TTcpClient,TRawSocket,TCGIRequest,TClientSocket等等。 They are all badly documented- very hard to find usage examples. 它们都记录错误 - 很难找到用法示例。 I tried using TTcpClient but sometimes the program freezes and then hits a timeout and I have no idea why. 我尝试使用TTcpClient,但有时程序冻结,然后达到超时,我不知道为什么。 Looks like a problem while waiting for responses. 在等待回复时看起来像是一个问题。 This is surely not a server problem because I test on localhost. 这肯定不是服务器问题,因为我在localhost上测试。 What is the best socket to use to work with HTTP protocol? 使用HTTP协议的最佳套接字是什么? Something easy to use? 容易使用的东西?

I want to use in both Delphi 7 and XE2. 我想在Delphi 7和XE2中使用。 I don't want to use anything WinAPI like, so I don't have to deal with PChars and other non-Delphi things. 我不想使用任何类似WinAPI的东西,所以我不必处理PChars和其他非Delphi的东西。

I am thinking of something like, either: 我想的是:

1) Does exactly what I want- downloads multiple pieces with progressbars of many files at the same file 1)完全符合我的要求 - 在同一文件中使用许多文件的进度条下载多个部分

OR 要么

2) Something like telnet- so I just write HTTP commands as strings and I get arrays of bytes in return which I can either transform into strings or save into tstreams. 2)像telnet这样的东西 - 所以我只是把HTTP命令写成字符串,我得到了返回的字节数组,我可以将其转换为字符串或保存到tstream中。

I cannot comment on the other libraries, but Indy supports everything you are asking for. 我不能评论其他图书馆,但Indy支持你要求的一切。

The TIdHTTP component can download files using byte ranges, if the server supports it. 如果服务器支持, TIdHTTP组件可以使用字节范围下载文件。 You can use the TIdHTTP.Head() method to check if the server return a Accept-Ranges: bytes header for a given URL. 您可以使用TIdHTTP.Head()方法检查服务器是否返回给定URL的Accept-Ranges: bytes标头。 If it does, then you can set the TIdHTTP.Request.ContentRangeStart and TIdHTTP.Request.ContentRangeEnd properties to the desired byte offets as needed when downloading the data from that URL. 如果是,则可以在从该URL下载数据时根据需要将TIdHTTP.Request.ContentRangeStartTIdHTTP.Request.ContentRangeEnd属性设置为所需的字节。 To download multiple parts of a resource at the same time, simply run multiple threads, each with its own TIdHTTP component, in parallel. 要同时下载资源的多个部分,只需并行运行多个线程,每个线程都有自己的TIdHTTP组件。 You will have to then either download multiple pieces to separate temp files and then merged them together into the final file when finished, or else create a single pre-sized file and then open multiple TFileStream objects to it at the desired starting offsets for TIdHTTP to write to. 然后,您必须先将多个部分下载到单独的临时文件中,然后在完成时将它们合并到最终文件中,或者创建一个预先调整大小的文件,然后在TIdHTTP所需的起始偏移处打开多个TFileStream对象。写给。

TIdHTTP supports cookies. TIdHTTP支持cookie。 You can either assign a TIdCookieManager component to the TIdHTTP.CookieManager property, or you can leave it unassigned and TIdHTTP will create a TIdCookieManager object internally. 您可以将TIdCookieManager组件分配给TIdHTTP.CookieManager属性,也可以将其保留为未分配状态, TIdHTTP将在内部创建TIdCookieManager对象。 Either way, also set the TIdHTTP.AllowCookies property to True. 无论哪种方式,还将TIdHTTP.AllowCookies属性设置为True。

Website login be accomplished one of two different ways, depending on whether the server uses HTTP-based authentication or WebForm-based authentication: 网站登录可以通过两种不同的方式完成,具体取决于服务器是使用基于HTTP的身份验证还是基于WebForm的身份验证:

  1. For HTTP authentication, add desired IdAuthentication... units to your uses clause, like IdAuthentacationDigest and IdAuthenticationNTLM , or the IdAllAuthentications unt, to register individual authentication classes with TIdHTTP , and then set the TIdHTTP.Request.UserName and TIdHTTP.Request.Password properties as needed. 对于HTTP认证,加入所需IdAuthentication...单位的uses条款,如IdAuthentacationDigestIdAuthenticationNTLM ,或IdAllAuthentications UNT,登记个人认证班, TIdHTTP ,然后设置TIdHTTP.Request.UserNameTIdHTTP.Request.Password性质如所须。 If the WebServer asks for authentication during a request, TIdHTTP will pick the appropriate class and use it to login with the specified credentials. 如果WebServer在请求期间请求身份验证, TIdHTTP将选择适当的类并使用它以指定的凭据登录。 If the server rejects the credentials, the TIdHTTP.OnAuthorization event will be fired to give you a chance to change the credentials and try again. 如果服务器拒绝凭据,则会触发TIdHTTP.OnAuthorization事件,以便您有机会更改凭据TIdHTTP.OnAuthorization试。

  2. For WebForm authentication, there is a TIdMultipartFormDataStream class that can be passed to the TIdHTTP.Post() method for posting a multipart/form-data formatted POST request. 对于WebForm身份验证,有一个TIdMultipartFormDataStream类,可以将其传递给TIdHTTP.Post()方法,以发布multipart/form-data格式的POST请求。

TIdHTTP in Indy 10 supports gzip-files and deflate-compressed files ( TIdHTTP in Iny 9 and earlier does not support compression). Indy 10中的TIdHTTP支持gzip文件和deflate压缩文件( TIdHTTP 9及更早版本中的TIdHTTP不支持压缩)。 You can assign a TIdZLibCompressorBase -derived component, such as TIdCompressorZLib , to the TIdHTTP.Compressor property, and TIdHTTP will handle all of the details for you, including sending an appropriate Accept-Encoding request header, and checking the server's Transfer-Encoding response header. 您可以将TIdZLibCompressorBase派生的组件(例如TIdCompressorZLib分配给TIdHTTP.Compressor属性, TIdHTTP将为您处理所有详细信息,包括发送适当的Accept-Encoding请求标头,以及检查服务器的Transfer-Encoding响应标头。

TIdHTTP has OnWorkBegin , OnWork , and OnWorkEnd events that can be used for progress bar and such. TIdHTTP具有OnWorkBeginOnWorkOnWorkEnd事件,可用于进度条等。 The OnWorkBegin event has an AWorkCountMax parameter that specifies the total number of bytes being transferred if known, otherwise it will be 0 (HTTP responses that use a Content-Length header will set the AWorkCountMax accordingly, but HTTP responses that use a Transfer-Encoding: chunked header will not). OnWorkBegin事件具有AWorkCountMax参数,该参数指定已知的传输的总字节数,否则它将为0(使用Content-Length标头的HTTP响应将相应地设置AWorkCountMax ,但使用Transfer-Encoding: chunked HTTP响应Transfer-Encoding: chunked header不会)。 The OnWork event has an AWorkCount parameter that specifies how many bytes have been transferred so far, regardless of the AWorkCounMax value. OnWork事件具有AWorkCount参数,该参数指定到目前为止已传输的字节数,与AWorkCounMax值无关。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM