[英]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.ContentRangeStart
和TIdHTTP.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的身份验证:
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
条款,如IdAuthentacationDigest
和IdAuthenticationNTLM
,或IdAllAuthentications
UNT,登记个人认证班, TIdHTTP
,然后设置TIdHTTP.Request.UserName
和TIdHTTP.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
试。
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
具有OnWorkBegin
, OnWork
和OnWorkEnd
事件,可用于进度条等。 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.