http://blog.9cbs.net/huangyaoshifog/archive/2004/08/20/79728.aspx
HTTP protocol using socket realize direct (download only) Author: querw
Download Source Code From the HTTP server to download a file with a lot of methods, "enthusiastic" Microsoft provides Wininet classes, which is also very convenient. Of course, we can also implement these functions themselves. It is easy to achieve breakpoint resume and check updates by formatting the request. There is a support for the HTTP1.1 protocol that provides the HTTP1.1 protocol, directly using the Socket to implement the DLL of the download function, and implement the following functions:
Connecting the host formatting request head settings, send timeout reception and analyzing response
Connection, send, set timeout, receive data, I will not say, Windows Socket is ready, and the corresponding function is OK. To download the file from the server, you must first send a request to the server. The HTTP request head consists of several row strings. The format of the HTTP request header is explained below. Suppose you want to download http://www.sina.com.cn/index.html this page, then the request head is as follows: Chapter 1: Method, request content, HTTP protocol version download can generally use GET methods, request The content is "/index.html" The version of the HTTP protocol refers to the version supported by the browser. It doesn't matter for downloading software, so use the 1.1 version "http / 1.1"; "get /index.html http / 1.1" 2 lines: Host name, format is "Host: Host" in this example: "Host: www.sina.com.cn" line 3: Accepted data type, the download software must be received all data types, so : "Accept: * / *" Chapter 4: Specify the type of browser to increase or decrease some content according to the different types of customer server, you can write this in this example:
"User-agent: mozilla / 4.0 (compatible; msie 5.00; windows 98)"
Chapter 5: The connection setting is set to keep the connection: "Connection: Keep-alive" Chapter 6: To achieve the breakpoint, you want to specify where to receive data, the format is as follows:
"Range: Bytes = Start Location - Termination Location"
For example, you can read the first 500 bytes to write this: "Range: Bytes = 0 - 499"; starts from the 1000th byte:
Range: Bytes = 999 - "
Finally, don't forget to add a row of space, indicating the end of the request head. The entire request head is as follows:
Get /index.html http / 1.1
Host: www.sina.com.cn
Accept: * / *
User-agent: mozilla / 4.0 (compatible; msie 5.00; windows 98)
Connection: Keep-alive
Chttpsocket provides a FormatRequestHeader () function to format the output HTTP request header. code show as below:
/ / Output HTTP request head according to the relative URL of the request
Const Char * Chttpsocket :: FormatRequestHeader (Char * PServer, Char * POBJECT, LONG & LENGTH,
Char * Pcookie, Char * Preferer, Long NFROM,
Long NTO, INT NSERVERTYPE) {
Char szport [10];
Char sztemp [20];
Sprintf (Szport, "% D", M_Port);
MEMSET (M_RequestHeader, '' / 0 '', 1024);
/// Chapter 1: Method, the path, version, version
STRCAT (M_RequestHeader, "Get");
STRCAT (M_RequestHeader, POBJECT);
STRCAT (M_RequestHeader, "http / 1.1");
STRCAT (M_RequestHeader, "/ R / N");
/// 2nd line: host
STRCAT (M_RequestHeader, "Host:");
STRCAT (M_RequestHeader, PServer);
STRCAT (M_RequestHeader, "/ R / N");
/// Chapter 3:
IF (prefere! = null)
{
STRCAT (M_RequestHeader, "Referr:");
STRCAT (M_RequestHeader, Preferer);
STRCAT (M_RequestHeader, "/ R / N");
}
/// Chapter 4: Received data type
STRCAT (M_RequestHeader, "Accept: * / *");
STRCAT (M_RequestHeader, "/ R / N");
/// Chapter 5: Browser type
STRCAT (M_RequestHeader, "User-Agent: Mozilla / 4.0 (Compatible; Msie 5.00; Windows 98));
STRCAT (M_RequestHeader, "/ R / N");
/// Chapter 6: Connection settings, keep
STRCAT (M_RequestHeader, "Connection: Keep-Alive");
STRCAT (M_RequestHeader, "/ R / N");
/// Chapter 7: cookie.
IF (Pcookie! = NULL)
{
STRCAT (M_RequestHeader, "SET Cookie: 0");
STRCAT (M_RequestHeader, Pcookie);
STRCAT (M_RequestHeader, "/ R / N");
}
/// Chapter 8: Request data start byte position (key to resume breakpoint)
IF (nfrom> 0)
{
STRCAT (M_RequestHeader, "Range: Bytes =");
_LTOA (NFROM, SZTEMP, 10);
STRCAT (M_RequestHeader, SzTemp);
STRCAT (M_RequestHeader, "-");
IF (NTO> NFROM)
{
_LTOA (NTO, SZTEMP, 10);
STRCAT (M_RequestHeader, SzTemp);
}
STRCAT (M_RequestHeader, "/ R / N");
}
/// Last line: blank line
STRCAT (M_RequestHeader, "/ R / N");
/// Return the result
Length = strlen (M_RequestHeader);
Return M_RequestHead;
}
When the request is sent to the server, you can receive the response from the server. The response head is also composed of several row strings, except for the first row and the last space, each line consists of one domain and a value. The first line includes the response state of the server, from 2xx to 5xx, each status code has different meaning, details can be viewed by RFC documentation
Downloading requires: 2xx Successful, you can continue to read data; 3xx indicate the target has been transferred, the new address is in the "location" domain; 4XX means the client is fault, may be the download address is wrong, wait; 5xx Representation server End dislocation. The field in the head is "Content-Length", "Accept-Ranges", "Content-Type", "Date", "Last-Modified", "Location", etc., download more concerned "Content- Length "Domain and" Location "domain. "Content-Length" means the size of the download file, "location" indicates the actual storage location of the target, and when the response code is 3XX, use the value in this domain to reconnect. The CHTTPSocket class in the attached source provides the following methods, used to read the server status code, the value of a domain, the response head and the entire response head:
INT getServerstate (); // Return to server status code-1 means unsuccessful
INT getfield (const char * szsession, char * szvalue, int nmaxlength); // Returns a domain value, -1 means unsuccessful
Int getResponseline (Char * pline, int nmaxlength); // Get a line of returning
Const Char * GetResponseHeader (INT & Length);
After obtaining the response, if the response code is 2xx and "content-length" does not equal 0, it means that the download file data can be received, the next job is very simple, call chttpsocket :: removeVie () until the received data The length is equal to the value of "content-length". A complete use process consists of the following steps:
Call the AFXPARSEURL () Analysis URL gets the server and download path; call chttpsocket :: socket () Create a socket; call chttpsocket :: connection () connection server; call chttpsocket :: formatRequestHeader () formatted request head; call chttpsocket :: SendRequest () Send a request header to the server; call chttpsocket :: getServersTate () get the response status code; call chttpsocket :: getfield ("content-length") get the size of the download file; call chttpsocket :: remove () Receive data until data Receive completion;
The source code supplied from this article also includes an example engineering using the Chttpsocket implementation download function. Note that all calls are blocked, so it is best to create a thread for a download task, otherwise it will cause the interface to respond to user input. The program running interface is shown below: This figure shows the request head, the response head, and the download progress. Of course, there are many jobs to do with multi-task multithreaded downloads. This article only discusses one possibility of downloading yourself, I hope to help readers. Welcome to Mail advice.