SoFunction
Updated on 2025-03-07

C# Implementation of breakpoint continuous transmission

Author: sparkdev
Source:/sparkdev/

Note that the breakpoint continuation mentioned in this article specifically refers to the breakpoint continuation in the HTTP protocol. This article mainly talks about ideas and key codes. For more details, please refer to the demo attached to this article.

How it works

Some request/response headers are defined in the HTTP protocol, which are used in combination. We can request only part of the data in one file in one HTTP request. In this way, we can save the downloaded data, and only request the remaining data next time, and complete the merge work after all the data is downloaded locally.

The HTTP protocol states that the range of requested data can be specified through the Range header in HTTP requests. The use of Range header is also very simple, just specify the following format:

Range: bytes=500-999

It means that only the 500th to 999th of the target file are requested.

For example, I have a file of 1000 bytes that needs to be downloaded. The first request does not require a Range header to indicate the download of the entire file. But after downloading the 499th byte, the download was cancelled. Then when you request to download the same file next time, you only need to download the data from 500th to 999th bytes. The principle seems simple, but we need to consider the following issues:

1. Do all web servers support Range headers?
2. There may be a long time interval between multiple requests. What should I do if the files on the server change?
3. How to save some downloaded data and related information?
4. When we spell a file into its original size through byte operations, how do we verify that it is exactly the same as the source file?

Let’s explore some details of the breakpoint continuation with these questions.

Check the server-side support for breakpoint continuous transmission

When the server responds to our request, it indicates in the response header whether to accept part of the data of a resource requested. But there seems to be a small trap here, that is, different servers may return different values ​​to indicate that they can accept requests for some resources. The seemingly unified method is that when the server does not support requesting part of the data, it will return Accept-Ranges: none. We just need to judge whether this return value is equal to none. The code is as follows:

private static bool IsAcceptRanges(WebResponse res)
{
  if (["Accept-Ranges"] != null)
  {
    string s = ["Accept-Ranges"];
    if (s == "none")
    {
      return false;
    }
  }
  return true;
}

Check whether the server-side file changes

When we download a part of a file, we may continue to download it immediately, or we may download it again after a while, or we may never continue to download it again...
The question here is, when you want to continue downloading, how to determine whether the file on the server is or the file that was half downloaded at the beginning. If the file on the server has been updated, you need to download it again from scratch anyway. Only when the files on the server have not changed can the breakpoint be continued to make sense.
For this question, the HTTP response header provides us with different options. Both ETag and Last-Modified can complete tasks.

Let's look at ETag first:

The ETag response-header field provides the current value of the entity tag for the requested variant. (Quoted from RFC2616 14.19 ETag)
To put it simply, ETag is a string that identifies the current requested content. When the requested resource changes, the corresponding ETag will also change. OK, the easiest way is to save the ETag in the response header on the first request and compare the next time you request it. The code is as follows:

string newEtag = GetEtag(response);
// tempFileName refers to some file contents that have been downloaded to the local area.// tempFileInfoName refers to a temporary file that saves the content of the Etagif ((tempFileName) && (tempFileInfoName))
{
  string oldEtag = (tempFileInfoName);
  if (!(oldEtag) && !(newEtag) && newEtag == oldEtag)
  {
  // Etag has not changed, you can continue to pass the breakpoint    resumeDowload = true;
  }
}
else
{
  if (!(newEtag))
  {
    (tempFileInfoName, newEtag);
  }
}
private static string GetEtag(WebResponse res)
{
  if (["ETag"] != null)
  {
    return ["ETag"];
  }
  return null;
}

Let's take a look at Last-Modified:

The Last-Modified entity-header field indicates the date and time at which the origin server believes the variant was last modified. (Quoted from RFC2616 14.29 Last-Modified)
Last-Modified is the last time the requested resource is modified on the server. The usage method is roughly the same as ETag.

I personally feel that using either ETag and Last-Modified can achieve our purpose. But you can also use both to do double check. Who knows whether the implementation of the web server strictly follows the HTTP protocol!

Save intermediate results

Here we mainly use C# for file operations. The general idea is that if there is an undownloaded file, add the newly downloaded bytes to the end of the file. No longer talkative. If you are interested, please read the demo code directly.

Verify files

During the process of breakpoint continuous transmission, we download and merge files in units of byte. If there are no exceptions in the whole process, the files we get may be different from the source files. Therefore, it is best to be able to verify the downloaded files once. But this is also the most difficult and difficult to achieve. Because it requires server-side support, for example, the server-side provides a downloadable file while providing the MD5 hash of the file. Of course, if we created the server side ourselves, we can implement it. But how can we require existing web servers to provide such functions!

demo

The above is the detailed content of the implementation of C# breakpoint continuous transmission. For more information about C# breakpoint continuous transmission, please pay attention to my other related articles!