linux socket類比HTTP請求上傳資料

來源:互聯網
上載者:User

    這是用socket類比HTTP請求上傳檔案的的C++代碼,裡面有一些從網上摘錄的代碼,我在這裡按我的需求整理後,再次分享出來,一是算作個人筆記,二是為廣大看官遇到類似的問題作參考!

#include <string.h>#include <stdlib.h>#include <algorithm>#include <fstream>#include <iostream>using namespace std;#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#define SEND_RQ(MSG) send(sock,MSG,strlen(MSG),0);#define _DEBUG_PRINT(X) Xint FindContentLength(string header);int RecvHttpHeader(int socket, string& header);int RecvHttpBody(int socket, string& body, int contentLength);int request(char* hostname, int port, char* url){struct sockaddr_in sin;int sock = socket (AF_INET, SOCK_STREAM, 0);if (sock == -1) {_DEBUG_PRINT(cout<<"create socket error!"<<endl);return -100;}sin.sin_family = AF_INET;sin.sin_port = htons( (unsigned short)port);//sin.sin_addr.s_addr = inet_addr(hostname);inet_pton(AF_INET, hostname, (void*)&sin.sin_addr);_DEBUG_PRINT( cout<<"Port :"<<sin.sin_port<<", Address : "<< sin.sin_addr.s_addr<<endl);int result = connect (sock,(const struct sockaddr *)&sin, sizeof(sockaddr_in) );if(result != 0) {_DEBUG_PRINT(cout<<"connect failed"<<endl);return -101;}SEND_RQ("POST ");SEND_RQ(url);SEND_RQ(" HTTP/1.1\r\n");SEND_RQ("Accept: text/html, image/jpeg, application/x-ms-application, */*\r\n");SEND_RQ("User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:17.0) Gecko/17.0 Firefox/17.0\r\n");SEND_RQ("Accept-Language: zh-CN,en-US;q=0.5\r\n");SEND_RQ("Accept-Encoding: gzip, deflate\r\n");SEND_RQ("Host: ");SEND_RQ(hostname);SEND_RQ("\r\n");char *boundary = (char *)"---------------------------41184676334";char content_type[512];memset(content_type, 0, 512);strcat(content_type, "Content-Type: multipart/form-data; boundary=");strcat(content_type, boundary);strcat(content_type, "\r\n");//--Construct request data {filePath, file}char content_before[4096];memset(content_before, 0, 4096);strcat(content_before, "--");strcat(content_before, boundary);strcat(content_before, "\r\n");strcat(content_before, "Content-Disposition: form-data; name=\"filePath\"\r\n\r\n");strcat(content_before, destPath);strcat(content_before, "\r\n");strcat(content_before, "--");strcat(content_before, boundary);strcat(content_before, "\r\n");strcat(content_before, "Content-Disposition: form-data; name=\"file\"; filename=\"");strcat(content_before, filename);strcat(content_before, "\"\r\n");strcat(content_before, "Content-Type: application/octet-stream\r\n\r\n");//strcat(content_before, "Content-Type: image/jpeg\r\n\r\n");char content_end[1024];memset(content_end, 0, 1024);strcat(content_end, "\r\n");strcat(content_end, "--");strcat(content_end, boundary);strcat(content_end, "--\r\n");// store the full name of fileifstream fin("/home/abc/test/enjoyor.mp4" ,ios::in|ios::binary);if(!fin){_DEBUG_PRINT(cout<<"File open error!\n");close(sock);return -102;}//---get the length of the fileint temp = fin.tellg();fin.seekg(0,ios_base::end);int len = fin.tellg();fin.seekg(temp);char *lenstr;lenstr = (char*)malloc(128);sprintf(lenstr, "%d", (strlen(content_before)+len+strlen(content_end)));strcat(content_type, "Content-Length: ");strcat(content_type, lenstr);strcat(content_type, "\r\n\r\n");free(lenstr);SEND_RQ(content_type);_DEBUG_PRINT(cout<<content_type);SEND_RQ(content_before);_DEBUG_PRINT(cout<<content_before);char c[1024];memset(c, 0,1024);int tmpLen=0;while(!fin.eof()){if(tmpLen<(len/1024)*1024){fin.read(c, 1024);send(sock,c,1024,0);sleep(0.001); //milisecondtmpLen+=1024;}else{fin.read(c,len-(len/1024)*1024);send(sock,c,len-(len/1024)*1024,0);break;}}fin.close();SEND_RQ(content_end);string header;int headerLength = RecvHttpHeader(sock,header);if(headerLength > 0){if(header.find("200") != string::npos) //HTTP/1.1 200 OK{int contentLength = FindContentLength(header);if(contentLength > 0){string strBody;RecvHttpBody(sock,strBody,contentLength);_DEBUG_PRINT(cout<<"the sRecvBuf is "<<strBody.c_str()<<endl);}}else //HTTP/1.1 400 or else{_DEBUG_PRINT(cout<<"unexpected http header status!"<<endl);close(sock);return -103;}}else{_DEBUG_PRINT(cout<<"the return string is not http protptype"<<endl);close(sock);return -104;}close(sock);return 0;}int FindContentLength(string header){transform(header.begin(),header.end(),header.begin(),(int(*)(int)) tolower);string::size_type pos = header.find("content-length",0);if(pos != string::npos){string::size_type posEnd = header.find("\r\n",pos);string contentString = header.substr(pos,posEnd - pos);_DEBUG_PRINT(cout<<contentString.c_str());pos = contentString.find(":",0);string strLength = contentString.substr(pos + 1);return (int)std::strtol(strLength.c_str(),NULL,10);    }return 0;}//receive header//param: socketId,receivedStringint RecvHttpHeader(int socket, string& header){header.clear();char chRecvBuf[1];//endBytes[]{'\r', '\n', '\r', '\n'}char endBytes[] = { 13, 10, 13, 10 };int posCompare = 0;while(true){int b = recv(socket,chRecvBuf,1,0);if (b == -1)return -1;header.append(chRecvBuf,1);if(endBytes[posCompare] == chRecvBuf[0]){posCompare++;if (posCompare == sizeof(endBytes)){break;}}else{posCompare = 0;}}return header.length();}//receive http response bodyint RecvHttpBody(int socket, string& body, int contentLength){body.clear();char chRecvBuf[1024];while (body.length() < contentLength){memset(chRecvBuf,0,sizeof(chRecvBuf));int b = recv(socket,chRecvBuf,sizeof(chRecvBuf) - 1,0);if (b == -1)return -1;body.append(chRecvBuf);}return body.length();}

想瞭解HTTP上傳請求的資料格式,可見我之前的一篇部落格http://blog.csdn.net/ronux/article/details/8244840。

參考:http://www.codeguru.com/cpp/i-n/internet/http/article.php/c8813/HTTP-Post-Using-C.htm

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.