Many people have experienced the use of network ant financial or network Express software to download Internet Files. The use of these software can greatly speed up the transmission of files on the Internet and reduce the time for file transmission. Why are these software so powerful? The main reason is that these software uses multi‑thread download and resumable data transfer. If we compile Program And can quickly download files on the Internet. Next I will explain how to use the C # language to compile a program that supports multi-threaded File Download. You will see how easy it is to use the C # language to compile network applications, you can also learn about the powerful network functions in C.
First introduce the HTTP protocol, HTTP
That is, hpyer text transfer
Protocal is the most important network protocol on the modern Internet. Hypertext Transfer Protocol is located at the application layer of TCP/IP protocol, is a connectionless, simple, and fast C/S knot.
The protocol. The HTTP process is divided into four steps: connection, request, response, and disconnection. C # language provides good support for the HTTP protocol. net Class Library provides the webrequest and webresponse classes, both of which are included in the system. in the. NET namespace, using these two classes can implement many advanced network functions.
Download is implemented using these two classes.
Both webrequest and webresponse are abstract base classes. Therefore, they cannot be used directly as objects in a program and must be inherited. In actual use, you can follow
Use their appropriate subclass for the fix. For Uris such as HTTP, The httpwebrequest and httpwebresponse classes can be used to process client programs and web servers.
HTTP Communication.
The httpwebrequest class provides many advanced functions for accessing files on Web Servers through HTTP. Httpwebrequest
The defined attributes and methods are supported. httpwebrequest exposes the values of public HTTP headers sent to Internet resources as attributes, which are set by methods or systems.
Or the HTTP header set by the method is: Accept, set by the accept attribute, connection, set by the connection attribute and keepalive attribute,
Content-Length, set by the contentlength attribute, content-type, set by the contenttype attribute, range,
Set by the addrange method. In actual use, the header information is correctly set and passed to the Web server. The web server responds as required.
The httpwebresponse class is inherited from the webresponse class and is used to handle the HTTP response returned from the web server.
This class implements many methods and has many attributes that can fully process received Internet information. In the httpwebresponse class, for most common HTTP header fields,
Each has an independent attribute corresponding to it. The programmer can use these attributes to conveniently access the information in the header field of the HTTP received message. In this example, the httpwebresponse class attribute is used.
Contentlength: the length of the received content.
With the above understanding, let's take a look at the usage of these two classes. To create an httpwebrequest object, do not directly use the HTTP webrequest constructor, but use webrequest. the create method initializes an httpwebrequest instance, for example:
| Httpwebrequest HWR = (httpwebrequest) webrequest. Create (http://www.163.com /); |
After this object is created, you can set the content of many HTTP header fields through the httpwebrequest attribute, such as HWR. addrange (,); set the receiving object range to-bytes.
When the httpwebreques object uses the getresponse () method, an httpwebresponse object is returned, which provides an HTTP Response Message.
You must use the getresponsestream () method of httpwebresponse. This method returns a stream object and can read the reports returned by HTTP.
For example, first define a strean object public system. Io. Stream ns; then NS = HWR. getresponse
(). Getresponsestream (); To create a stream object. With the above preparation knowledge, we will start to design our multi-threaded Internet File Download program, first open Visual Studio. NET
Integrated development environment, select "file", "new", "project", and then select "visual
C # project, select "Windows application" in the list box on the right of the wizard, enter the project name, for example: httpftp, and then select "OK". The wizard automatically generates
Windows application project. First, open the window designer design application window and add the following controls:
A listbox1 three text labels label1-label3 three text boxes textBox1-textBox3 a start receiving button button1 designed window such:
Control DefinitionCodeYes:
Public System. Windows. Forms. ListBox listbox1; Private system. Windows. Forms. Label label1; Private system. Windows. Forms. textbox textbox1 Private system. Windows. Forms. Button button1; Private system. Windows. Forms. Label label2; Private system. Windows. Forms. textbox textbox2; Private system. Windows. Forms. Label label3; Private system. Windows. Forms. textbox textbox3; Private system. Windows. Forms. Label label4; Private system. Windows. Forms. textbox textbox4; |
Open the form1 code editor and add the following namespace:
Using system. Net; // Network Function Using system. IO; // stream support Using system. Threading; // thread support |
Add the following program variables:
Public bool [] threadw; // indicates the end of each thread. Public String [] filenamew; // file name of the file received by each thread Public int [] filestartw; // start position of the file received by each thread Public int [] filesizew; // the size of the file received by each thread Public String strurl; // URL of the accepted File Public bool Hb; // file merging mark Public int thread; // number of processes |
Define an httpfile class to manage the receiving thread. The Code is as follows:
Public class httpfile { Public form1 formm; Public int threadh; // thread code Public String filename; // file name Public String strurl; // the URL of the received File Public filestream FS; Public httpwebrequest request; Public System. Io. Stream ns; Public byte [] nbytes; // receiving buffer Public int nreadsize; // number of received bytes Public httpfile (form1 form, int thread) // Constructor { Formm = form; Threadh = thread; } ~ Httpfile () // destructor { Formm. Dispose (); } Public void receive () // receiving thread { Filename = formm. filenamew [threadh]; Strurl = formm. strurl; NS = NULL; Nbytes = new byte [2, 512]; Nreadsize = 0; Formm. listbox1. Items. Add ("Thread" + threadh. tostring () + "start receiving "); FS = new filestream (filename, system. Io. filemode. Create ); Try { Request = (httpwebrequest) httpwebrequest. Create (strurl ); // Receiving start position and length Request. addrange (formm. filestartw [threadh], Formm. filestartw [threadh] + formm. filesizew [threadh]); NS = request. getresponse (). getresponsestream (); // get the receiving stream Nreadsize = NS. Read (nbytes, 0,512 ); While (nreadsize> 0) { FS. Write (nbytes, 0, nreadsize ); Nreadsize = NS. Read (nbytes, 0,512 ); Formm. listbox1. Items. Add ("Thread" + threadh. tostring () + "receiving "); } FS. Close (); NS. Close (); } Catch (exception ER) { MessageBox. Show (ER. Message ); FS. Close (); } Formm. listbox1. Items. Add ("process" + threadh. tostring () + "received! "); Formm. threadw [threadh] = true; } } |
This class is in the same namespace as the form1 class, but not included in the form1 class. The following defines the Event Response Function of the "start to receive" button control:
Private void button#click (Object sender, system. eventargs E) { Datetime dt = datetime. Now; // start receiving time Textbox1.text = DT. tostring (); Strurl = textbox2.text. Trim (). tostring (); Httpwebrequest request; Long filesize = 0; Try { Request = (httpwebrequest) httpwebrequest. Create (strurl ); Filesize = request. getresponse (). contentlength; // get the length of the target file Request. Abort (); } Catch (exception ER) { MessageBox. Show (ER. Message ); } // Number of receiving threads Thread = convert. toint32 (textbox4.text. Trim (). tostring (), 10 ); // Initialize the Array Based on the number of threads Threadw = new bool [thread]; Filenamew = new string [thread]; Filestartw = new int [thread]; Filesizew = new int [thread]; // Calculate the size of the file that each thread should receive Int filethread = (INT) filesize/thread; // average allocation Int filethreade = filethread + (INT) filesize % thread; // the remaining part is completed by the last thread. // Assign values to Arrays For (INT I = 0; I <thread; I ++) { Threadw [I] = false; // The initial value of each thread state is false. Filenamew [I] = I. tostring () + ". dat"; // The temporary file name of the file received by each thread If (I <thread-1) { Filestartw [I] = filethread * I; // The starting point for each thread to receive files Filesizew [I] = filethread-1; // The length of the file received by each thread } Else { Filestartw [I] = filethread * I; Filesizew [I] = filethreade-1; } } // Define the thread array and start the receiving thread Thread [] threadk = new thread [thread]; Httpfile [] httpfile = new httpfile [thread]; For (Int J = 0; j <thread; j ++) { Httpfile [J] = new httpfile (this, J ); Threadk [J] = new thread (New threadstart (httpfile [J]. Receive )); Threadk [J]. Start (); } // Start the file thread to merge received by each thread Thread hbth = new thread (New threadstart (hbfile )); Hbth. Start (); } |
The thread hbfile of the merged file is defined in the form1 class and defined as follows:
Public void hbfile () { While (true) // wait { HB = true; For (INT I = 0; I <thread; I ++) { If (threadw [I] = false) // There is a non-terminated thread, wait { HB = false; Thread. Sleep (100 ); Break; } } If (HB = true) // All threads are finished, stop waiting, { Break; } } Filestream FS; // start merging Filestream fstemp; Int readfile; Byte [] bytes = new byte [1, 512]; FS = new filestream (textbox3.text. Trim (). tostring (), system. Io. filemode. Create ); For (int K = 0; k <thread; k ++) { Fstemp = new filestream (filenamew [K], system. Io. filemode. Open ); While (true) { Readfile = fstemp. Read (bytes, 0,512 ); If (readfile> 0) { FS. Write (bytes, 0, readfile ); } Else { Break; } } Fstemp. Close (); } FS. Close (); Datetime dt = datetime. now; Textbox1.text = DT. tostring (); // End Time MessageBox. Show ("Received !!! "); } |
at this point, a program that downloads files with multiple threads is finished. Note that when you enter a local file name, enter the following format: "C: \ test \ httpftp \ bin \
d.htm ", because the character after" \ "is an escape character in C #, the larger the number of threads is, the better, generally, you can run the program on five threads in Visual Studio.. Net
2002 development environment and Windows XP operating system.