日期:2014-05-16 浏览次数:21011 次
这是用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) X
int 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 file
ifstream 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 file
int 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