linux 模拟socket请求,linux socket模拟HTTP请求上传数据

这是用socket模拟HTTP请求上传文件的的C++代码,里面有一些从网上摘录的代码,我在这里按我的需求整理后,再次分享出来,一是算作个人笔记,二是为广大看官遇到类似的问题作参考!

#include

#include

#include

#include

#include

using namespace std;

#include

#include

#include

#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<

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<

int result = connect (sock,(const struct sockaddr *)&sin, sizeof(sockaddr_in) );

if(result != 0) {

_DEBUG_PRINT(cout<

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<

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<

SEND_RQ(content_before);

_DEBUG_PRINT(cout<

char c[1024];

memset(c, 0,1024);

int tmpLen=0;

while(!fin.eof())

{

if(tmpLen

{

fin.read(c, 1024);

send(sock,c,1024,0);

sleep(0.001); //milisecond

tmpLen+=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<

}

}

else //HTTP/1.1 400 or else

{

_DEBUG_PRINT(cout<

close(sock);

return -103;

}

}

else

{

_DEBUG_PRINT(cout<

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<

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,receivedString

int 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 body

int 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();

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值