Use socket directly to implement HTTP protocol (dedicated for download)

Source: Internet
Author: User
Tags set cookie

Use socket directly to implement HTTP protocol (dedicated for download)

Author: que rongwen (querw)
Class 4, level 2 computer, North Polytechnic University

Download source code

There are many methods to download a file from an HTTP server. Microsoft, "enthusiastic", provides the WinInet class, which is also very convenient to use. Of course, we can also implement these functions by ourselves. By formatting the request header, we can easily implement resumable upload and check for updates. The project included in this article has a DLL that supports the HTTP1.1 protocol and directly uses Socket to implement the download function. It implements the following functions:

  1. Host connection
  2. Format Request Header
  3. Set receiving and sending timeout
  4. Receive and analyze Response Headers

I will not elaborate on connection, sending, setting timeout, and receiving data. windows socket has been ready for a long time and it will be okay to call the corresponding function.
To download files from the server, you must first send a request to the server. The HTTP Request Header consists of several line strings. The following uses an example to describe the HTTP Request Header Format. If you want to download the http://www.sina.com.cn/index.html web page, the request header is written as follows:

Row 1st: method, request content, HTTP Version
The GET method can be used for downloading. The request content is "/index.html". The HTTP Protocol version refers to the version supported by the browser. It does not matter when downloading software, therefore, the "HTTP/1.1" version 1.1 is used ";
& Quot; GET/index.html HTTP/1.1 & quot"

Row 3: Host name, in the format of "Host: Host"
In this example: "Host: www.sina.com.cn"

Row 3rd: accepted data type. Download Software must certainly receive all data types, so:
"Accept :*/*"

Row 4th: Specifies the browser type.
Some servers increase or decrease some content based on different types of customer servers. In this example, you can write:

“User-Agent:Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)”

Row 3: connection settings
Set to Keep Connection: "Connection: Keep-Alive"

Row 3: To implement resumable data transfer, specify the position from which data is received. The format is as follows:

"Range: bytes = start position-end position"

For example, you can write the first 500 bytes as follows: "Range: bytes = 0-499"; download from 1,000th bytes:

“Range: bytes=999 -”

Finally, do not forget to add a blank line to end the request header. The entire request header is as follows:

GET /index.html HTTP/1.1Host:www.sina.com.cnAccept:*/*User-Agent:Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)Connection:Keep-Alive

CHttpSocket provides the FormatRequestHeader () function to format the output HTTP request header. The Code is as follows:

/// Output the HTTP Request Header 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); // row 1st: method, Request Path, version strcat (m_requestheader, "GET"); strcat (m_requestheader, pObject ); strcat (m_requestheader, "HTTP/1.1"); strcat (m_r Equestheader, "/r/n"); // row 2nd: Host strcat (m_requestheader, "Host:"); strcat (m_requestheader, pServer); strcat (m_requestheader, "/r/n"); // row 3rd: if (pReferer! = NULL) {strcat (m_requestheader, "Referer:"); strcat (m_requestheader, pReferer); strcat (m_requestheader, "/r/n");} // row 4th: received data type strcat (m_requestheader, "Accept: */*"); strcat (m_requestheader, "/r/n"); // 5th rows: browser type strcat (m_requestheader, "User-Agent: Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)"); strcat (m_requestheader, "/r/n "); /// Row 3: Connection settings, Keep strcat (m_requestheader, "Connection: Keep-Alive"); strcat (m_requesth Eader, "/r/n"); // row 7th: Cookie. if (pCookie! = NULL) {strcat (m_requestheader, "Set Cookie: 0"); strcat (m_requestheader, pCookie); strcat (m_requestheader, "/r/n ");} /// Row 3: The starting byte location of the requested data (key to resumable data transfer) 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");} // The last line: empty line strcat (m_requestheader, "/r/n"); // return result Length = strlen (m_requestheader); return m_requestheader ;}

After sending the request hair to the server, you can receive the response header from the server. The response header is composed of several line strings. Except the first line and the last empty line, each line consists of a field and a value. The first line includes the server response status, from 2XX to 5XX. Each status code has a different meaning. For details, you can refer to the RFC document for downloading. Note: 2XX indicates that the request is successful, you can continue to read data. 3XX indicates that the target has been transferred, the new address is in the "Location" domain, 4XX indicates that the client is wrong, and may be wrong. 5XX indicates that the server is wrong. The fields in the Response Header include "Content-Length", "Accept-Ranges", "Content-Type", "Date", "Last-Modified", and "Location, the "Content-Length" domain and "Location" domain are the fields of interest for downloading. "Content-Length" indicates the size of the downloaded file, and "Location" indicates the actual storage Location of the target. When the response code is 3XX, reconnect with the value in this field.
The CHttpSocket class included in the source code provides the following methods to read the server status code, the value of a domain, a line in the response header, and the entire response header:

IntGetServerState (); // return the server status code-1, indicating that intGetField (const char * szSession, char * szValue, int nMaxLength) is unsuccessful; // return a Domain value, -1 indicates that intGetResponseLine (char * pLine, int nMaxLength) is unsuccessful. // you can call this operation to obtain a row of const char * GetResponseHeader (int & Length) in the return header );

After obtaining the response header, if the response code is 2XX and the value of "Content-Length" is not equal to 0, the system can receive the downloaded file data. The next step is very simple. Call CHttpSocket:: Recevie () until the received data Length is equal to the value of "Content-Length.
A complete procedure consists of the following steps:

  1. Call AfxParseURL () to analyze the URL to obtain the Server and download path;
  2. Call CHttpSocket: Socket () to create a Socket;
  3. Call CHttpSocket: Connect () to Connect to the server;
  4. Call CHttpSocket: FormatRequestHeader () to format the request header;
  5. Call CHttpSocket: SendRequest () to send the request header to the server;
  6. Call CHttpSocket: GetServerState () to obtain the response status code;
  7. Call CHttpSocket: GetField ("Content-Length") to get the size of the downloaded file;
  8. Call CHttpSocket: Receive () to Receive data until the data is received;

The source code included in this article also includes an example project that uses CHttpSocket to implement the download function. Note that all calls are blocked, so it is best to create a thread for a download task. Otherwise, the interface cannot respond to user input. Shows the program running interface:

This figure shows the request header, response header, and download progress.
Of course, there is still a lot to do to implement multi-task and multi-thread download. This article only discusses the possibility of downloading by yourself, hoping to help readers. Welcome to Mail for advice.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.