To meet the needs of the project, a C ++ HTTP request client is required to upload data to the server. The server uses the restful Web Service implemented by spring MVC, at first, the server was designed to accept data in byte [] format. After all, the server was written in Java and it is completely feasible to parse the received data stream into the corresponding file.
If anyone who has written HTTP requests in Java or other languages knows that the request method can be divided into get and post, but the data transmitted by get is simply a simple parameter at best, the data format at request time such as code, which is the request http://www.ip138.com: 8080/search. asp? Mobile = 1565888 & Action = mobile site request parameters:
GET /search.asp?mobile=1565888&action=mobile HTTP/1.1Host: www.ip138.com:8080User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:14.0) Gecko/20100101 Firefox/14.0.1Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3Accept-Encoding: gzip, deflateConnection: keep-alive
The preceding figure shows the data obtained using the Firefox plug-in live HTTP headers. In addition, this plug-in allows you to customize HTTP Request Parameters to facilitate programming testing. For details, refer to the relevant materials. Many parameters are not required, but it is best to set them to simulate the effect of the browser. In addition, you do not need to set the Content-Type and Content-Length parameters for GET requests. These two parameters are usually paired. The User-Agent is used to request the browser and OS information of the client. You can customize it by simulating browser access.
The data in the POST request is stored in the Request body. For details, refer to callback. Note the blank line between the request header and request data. This is the POST request data of a web system:
POST /myproject/infoUpdate HTTP/1.1Host: 192.168.52.250:8088User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:14.0) Gecko/20100101 Firefox/14.0.1Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3Accept-Encoding: gzip, deflateConnection: keep-aliveReferer: http://192.168.52.250:8088/myproject/infoUpdate.actionContent-Type: application/x-www-form-urlencodedContent-Length: 24infoId=3¤tPage=1
In addition, when organizing request information, \ r \ n is used as the line break in windows, but it is also good in Linux, although the line break in Linux is \ n.
strcat(requestStr, "POST ");strcat(requestStr, api);strcat(requestStr, " HTTP/1.1\r\n");strcat(requestStr, "Accept: application/x-ms-application, image/gif, ""application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/x-shockwave-flash, ""application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*\r\n");strcat(requestStr, "User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:17.0) Gecko/17.0 Firefox/17.0\r\n");strcat(requestStr, "Accept-Language: zh-CN,en-US;q=0.5\r\n");strcat(requestStr, "Accept-Encoding: gzip, deflate\r\n");strcat(requestStr, "Host: ");strcat(requestStr, hostname);strcat(requestStr, "\r\n");
Post can be done with simple data, but for uploading files. Files are generally in binary format, that is, to transmit streams. However, we are no stranger to the file form Uploaded By struts2 or spring MVC, So I monitored the request data for a file upload operation:
Post/myproject/infoupdate HTTP/1.1 HOST: 192.168.52.250: 8088user-agent: Mozilla/5.0 (Windows NT 6.1; RV: 14.0) Gecko/20100101 Firefox/14.0.1accept: text/html, application/XHTML + XML, application/XML; q = 0.9, */*; q = 0.8accept-language: ZH-CN, ZH; q = 0.8, en-us; Q = 0.5, en; q = 0.3accept-encoding: gzip, deflateconnection: Keep-alivecontent-type: multipart/form-data; boundary = ------------------------- 41184676334 Conte NT-length: 95254-----------------------------41184676334 \ r \ ncontent-Disposition: Form-data; name = "ID" \ r \ n \ r \ N6 \ r \ n ----------------------------- 41184676334 \ r \ ncontent-Disposition: Form-data; name = "Doc "; filename = "faq_info.jpg" \ r \ ncontent-type: image/JPEG \ r \ n ...... Requested data stream ...... \ R \ n ----------------------------- 41184676334 -- \ r \ n
Boundary (separator) is used to separate different request data, this is the data format required when the Content-Type type is multipart/form-data (Spring MVC restful Web Service also supports the multipart/mixed type for uploading files, it is the same as the & interval parameter when the Content-Type is application/X-WWW-form-urlencoded. For more information, see http://blog.csdn.net/mspinyin/article/details/6141638. For Java-version httpurlconnection requests, see http://lapulande.iteye.com/blog/719581. For C ++ versions, you can use Winsock in windows. For the code, refer to ghost. I suggest that you use a Java client to upload files. If the test passes, you can write c ++ code, in the request header part C ++, you can honestly organize the corresponding parameters. In the request data part, you must strictly note the line breaks, and the length of the uploaded file is added to the Content-Length (including the length of the uploaded data and other characters such as separators ).
The file stream length can be obtained as follows:
ifstream fin(filePath ,ios::in|ios::binary); if(!fin){ cout<<"File open error!\n"; return -1; } //---get the length of the file int temp = fin.tellg(); fin.seekg(0,ios_base::end); int len = fin.tellg(); fin.seekg(temp);
After obtaining the length, locate it again at the beginning of the file.
When uploading a file stream, you need to read the maximum number of sends. Otherwise, the server will get an error stream and do not use strlen (c) To specify the length of the sent stream during sending, because char * C may contain null characters such as '\ 0', an incorrect length is used.
Char C [1024]; memset (C,); int tmplen = 0; int I = 0; while (! Fin. EOF () {If (tmplen <(LEN/1024) * 1024) // first, {fin. read (C, 1024); send (sock, C, 1024, 0); sleep (1); // rest, in order to reduce CPU usage and take care of bandwidth tmplen + = ;} else // if the remaining bytes are less than or equal to 1024, send the remaining bytes separately {fin. read (C, len-(LEN/1024) * 1024); send (sock, C, len-(LEN/1024) *, 0); break;} fin. close ();
You can select TCP or UDP for requests created using socket in C ++ without using HTTP. TCP is used by default. When I used Wireshark to monitor the transmitted data in the test, I did not see the data in the HTTP-related protocol. The reason is that the Java version of the request can be detected.