一个HTTP.二进制POST和HTTP指定长度接收的C++实现

本文介绍了一个使用 C++ 编写的简单程序,该程序能够通过 TCP/IP 连接发送 HTTP Post 请求,并接收服务器响应。文章提供的源代码展示了如何构建请求报文、发送请求、接收并解析响应头部及主体内容。
None.gif// CppSocket.cpp : Defines the entry point for the console application.
None.gif
//
None.gif

None.gif#include 
"stdafx.h"
None.gif#include 
<cstdlib>
None.gif#include 
<string>
None.gif#include 
<algorithm>
None.gif#include 
<iostream>
None.gif#include 
<fstream>
None.gif#include 
<iterator>
None.gif#include 
<Winsock2.h>
None.gif
None.gif
using namespace std;
None.gif
#define MS_SOCKET 1
None.gif
None.gif#ifdef MS_SOCKET
None.gif
#define NULLCHAR 
None.gif
#define userlog printf 
None.gif
#endif
None.gif
int FindContentLength(string header);
None.gif
int RecvHttpHeader(int socket, string& header);
None.gif
int RecvHttpBody(int socket, string& body, int contentLength);
None.gif
long Post(const char * RemoteHostIP,int RemoteHostPort,const char *lpURL,const char *lpExtraHeaderInfo,string &strRecvBuf);
None.gif
None.gif
int _tmain(int argc, char* argv[])
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
if(argc < 5)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        cout 
<< "usage:cppsocket ip port url bodyFile " << endl 
InBlock.gif        
<<      "eg:   cppsockeet 127.0.0.1 80 /a.asp a.xml " << endl;
InBlock.gif        
return 1;
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
string ip(argv[1]);
InBlock.gif    
string port(argv[2]);
InBlock.gif    
string url(argv[3]);
InBlock.gif    
string bodyFile(argv[4]);
InBlock.gif    
string headerFile;
InBlock.gif    
if(argc > 5)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        headerFile 
= argv[5];
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    fstream fsbody(bodyFile.c_str());
InBlock.gif    
if(fsbody.good())
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        fsbody.unsetf(ios::skipws);
InBlock.gif        istream_iterator
<char> iterbody(fsbody);
InBlock.gif        
string strbody(iterbody,istream_iterator<char>());
InBlock.gif
InBlock.gif        
string strRecv;
InBlock.gif
InBlock.gif#ifdef MS_SOCKET
InBlock.gif     WSADATA wsaData;
InBlock.gif     
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
InBlock.gif     
if (iResult != NO_ERROR)
InBlock.gif        cout 
<< "Error at WSAStartup()" << endl;
InBlock.gif
#endif
InBlock.gif
InBlock.gif        Post(ip.c_str(),(
int)std::strtol(port.c_str(),NULL,10),url.c_str(),strbody.c_str(),strRecv);
InBlock.gif
InBlock.gif#ifdef MS_SOCKET
InBlock.gif        WSACleanup();
InBlock.gif
#endif
InBlock.gif        cout 
<< strRecv;
InBlock.gif
InBlock.gif        
//cin.get();
ExpandedSubBlockEnd.gif
    }

InBlock.gif    
else
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        cout 
<<  " can't open file " << bodyFile << " to read" << endl;
InBlock.gif        
return 2;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
return 0;
ExpandedBlockEnd.gif}

None.gif
None.gif
long Post(const char * RemoteHostIP,int RemoteHostPort,const char *lpURL,const char *lpExtraHeaderInfo,string &strRecvBuf)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
int SocketId,Result,optval=1;
InBlock.gif    
struct sockaddr_in sServerAddr;
InBlock.gif    
struct linger mylinger;
InBlock.gif
InBlock.gif    sServerAddr.sin_family         
= AF_INET;
InBlock.gif    sServerAddr.sin_addr.s_addr    
= inet_addr( RemoteHostIP );
InBlock.gif    
//sServerAddr->sin_addr.s_addr = INADDR_ANY;
InBlock.gif
    sServerAddr.sin_port           = htons( RemoteHostPort );
InBlock.gif
InBlock.gif#ifdef MS_SOCKET
InBlock.gif    
if((SocketId=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))<0)
InBlock.gif
#else
InBlock.gif    
if((SocketId=socket(AF_INET,SOCK_STREAM,0))<0)
InBlock.gif
#endif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{    
InBlock.gif        
return -1;
ExpandedSubBlockEnd.gif    }

InBlock.gif    mylinger.l_onoff  
= 1;
InBlock.gif    mylinger.l_linger 
= 0;
InBlock.gif
InBlock.gif    setsockopt(SocketId, SOL_SOCKET, SO_LINGER, 
InBlock.gif        (
char *&mylinger,sizeof(struct linger));
InBlock.gif#ifndef MS_SOCKET
InBlock.gif    sigset(SIGPIPE,SIG_IGN);
InBlock.gif
#endif
InBlock.gif
InBlock.gif    optval 
= 1;
InBlock.gif    setsockopt(SocketId, SOL_SOCKET, SO_KEEPALIVE, 
InBlock.gif        (
char *&optval,sizeof(int));
InBlock.gif
InBlock.gif    Result 
= connect(SocketId,(struct sockaddr*)&sServerAddr,sizeof(struct sockaddr_in));
InBlock.gif    
InBlock.gif    
if( Result != 0 )
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{    
InBlock.gif        shutdown( SocketId,
2 );
InBlock.gif#ifdef MS_SOCKET
InBlock.gif        ::closesocket(SocketId);
InBlock.gif
#else
InBlock.gif        close( SocketId );
InBlock.gif
#endif
InBlock.gif        userlog(
"function connect error, return Value is %d",Result);
InBlock.gif        
return -1;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    
//
InBlock.gif    
// Format the HTTP request
InBlock.gif    
//
InBlock.gif    
// request buffer 
InBlock.gif
    char szGetBuffer[8096];
InBlock.gif    
// input http command into request buffer and format it;
InBlock.gif
    sprintf(szGetBuffer,"POST %s HTTP/1.0\r\n""Content-Type:text/html;charset=gb2312;\r\n""Content-Length:%u\r\n"
InBlock.gif                
"\r\n"
InBlock.gif                
"%s"
InBlock.gif                
"\r\n\0",
InBlock.gif            lpURL, strlen(lpExtraHeaderInfo), lpExtraHeaderInfo);
InBlock.gif
InBlock.gif    
//发送Post请求
InBlock.gif
    Result = send(SocketId, szGetBuffer, strlen(szGetBuffer), 0);
InBlock.gif    
InBlock.gif    userlog(
" In Post function , the szGetBuffer is %s",szGetBuffer);
InBlock.gif
InBlock.gif    
if( Result == -1 )
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{    
InBlock.gif        shutdown( SocketId,
2 );
InBlock.gif#ifdef MS_SOCKET
InBlock.gif        ::closesocket(SocketId);
InBlock.gif
#else
InBlock.gif        close( SocketId );
InBlock.gif
#endif
InBlock.gif        userlog(
"function send error, return Value is %d",Result);
InBlock.gif        
return -1;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    
//userlog("function send success, the send string is \n %s \n return Value is %d",szGetBuffer,Result);
InBlock.gif
    
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//*
InBlock.gif     * 接受Post请求的返回结果
ExpandedSubBlockEnd.gif     
*/

InBlock.gif
InBlock.gif    
// recv http header
InBlock.gif
    string header;
InBlock.gif    
int headerLength = RecvHttpHeader(SocketId,header);
InBlock.gif    
if(headerLength > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
int contentLength = FindContentLength(header);
InBlock.gif
InBlock.gif        
if(contentLength > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
string strBody;
InBlock.gif
InBlock.gif            RecvHttpBody(SocketId,strBody,contentLength);
InBlock.gif            userlog(
"the sRecvBuf is %s",strBody.c_str());
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif    
else
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif            userlog(
"the return string is not http protptype");
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif#ifdef MS_SOCKET
InBlock.gif        ::closesocket(SocketId);
InBlock.gif
#else
InBlock.gif        close( SocketId );
InBlock.gif
#endif
InBlock.gif    
return 0;  //正常返回
ExpandedBlockEnd.gif
}

None.gif
None.gif
int FindContentLength(string header)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    std::transform(header.begin(),header.end(),header.begin(),(
int(*)(int)) tolower);
InBlock.gif    
InBlock.gif    
string::size_type pos = header.find("content-length",0);
InBlock.gif    
if(pos != string::npos)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
string::size_type posEnd = header.find("\r\n",pos);
InBlock.gif        
string contentString = header.substr(pos,posEnd - pos);
InBlock.gif        userlog(contentString.c_str());
InBlock.gif        pos 
= contentString.find(":",0);
InBlock.gif        
InBlock.gif        
string strLength = contentString.substr(pos + 1);
InBlock.gif
InBlock.gif        
return (int)std::strtol(strLength.c_str(),NULL,10);
ExpandedSubBlockEnd.gif    }

InBlock.gif    
return 0;
ExpandedBlockEnd.gif}

None.gif
None.gif
None.gif
int RecvHttpHeader(int socket, string& header)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    header.clear();
InBlock.gif
InBlock.gif    
char chRecvBuf[1];
InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif    
char endBytes[] = dot.gif13101310 };
InBlock.gif    
int posCompare = 0;
InBlock.gif    
while (true
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif
InBlock.gif        
int b = recv(socket,chRecvBuf,1,0);
InBlock.gif        
if (b == -1)
InBlock.gif            
return -1;
InBlock.gif
InBlock.gif        header.append(chRecvBuf,
1);
InBlock.gif        
InBlock.gif        
if (endBytes[posCompare] == chRecvBuf[0]) 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            posCompare
++;
InBlock.gif            
if (posCompare == sizeof(endBytes)) 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
break;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
else 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            posCompare 
= 0;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
return header.length();        
ExpandedBlockEnd.gif}

None.gif
None.gif
None.gif
int RecvHttpBody(int socket, string& body, int contentLength)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    body.clear();
InBlock.gif
InBlock.gif    
char chRecvBuf[1024];
InBlock.gif
InBlock.gif    
while (body.length() < contentLength) 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        memset(chRecvBuf,
0,sizeof(chRecvBuf));
InBlock.gif        
int b = recv(socket,chRecvBuf,sizeof(chRecvBuf) - 1,0);
InBlock.gif        
if (b == -1)
InBlock.gif            
return -1;
InBlock.gif
InBlock.gif        body.append(chRecvBuf);
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
return body.length();        
ExpandedBlockEnd.gif}

None.gif

转载于:https://www.cnblogs.com/evlon/archive/2007/08/13/853145.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值