现在的位置: 首页 > 综合 > 正文

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

2011年07月01日 ⁄ 综合 ⁄ 共 5516字 ⁄ 字号 评论关闭
// CppSocket.cpp : Defines the entry point for the console application.
//

#include 
"stdafx.h"
#include 
<cstdlib>
#include 
<string>
#include 
<algorithm>
#include 
<iostream>
#include 
<fstream>
#include 
<iterator>
#include 
<Winsock2.h>

using namespace std;
#define MS_SOCKET 1

#ifdef MS_SOCKET
#define NULLCHAR 
#define userlog printf 
#endif
int FindContentLength(string header);
int RecvHttpHeader(int socket, string& header);
int RecvHttpBody(int socket, string& body, int contentLength);
long Post(const char * RemoteHostIP,int RemoteHostPort,const char *lpURL,const char *lpExtraHeaderInfo,string &strRecvBuf);

int _tmain(int argc, char* argv[])
{
    
if(argc < 5)
    
{
        cout 
<< "usage:cppsocket ip port url bodyFile " << endl 
        
<<      "eg:   cppsockeet 127.0.0.1 80 /a.asp a.xml " << endl;
        
return 1;
    }


    
string ip(argv[1]);
    
string port(argv[2]);
    
string url(argv[3]);
    
string bodyFile(argv[4]);
    
string headerFile;
    
if(argc > 5)
    
{
        headerFile 
= argv[5];
    }


    fstream fsbody(bodyFile.c_str());
    
if(fsbody.good())
    
{
        fsbody.unsetf(ios::skipws);
        istream_iterator
<char> iterbody(fsbody);
        
string strbody(iterbody,istream_iterator<char>());

        
string strRecv;

#ifdef MS_SOCKET
     WSADATA wsaData;
     
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
     
if (iResult != NO_ERROR)
        cout 
<< "Error at WSAStartup()" << endl;
#endif

        Post(ip.c_str(),(
int)std::strtol(port.c_str(),NULL,10),url.c_str(),strbody.c_str(),strRecv);

#ifdef MS_SOCKET
        WSACleanup();
#endif
        cout 
<< strRecv;

        
//cin.get();
    }

    
else
    
{
        cout 
<<  " can't open file " << bodyFile << " to read" << endl;
        
return 2;
    }

    
return 0;
}


long Post(const char * RemoteHostIP,int RemoteHostPort,const char *lpURL,const char *lpExtraHeaderInfo,string &strRecvBuf)
{
    
int SocketId,Result,optval=1;
    
struct sockaddr_in sServerAddr;
    
struct linger mylinger;

    sServerAddr.sin_family         
= AF_INET;
    sServerAddr.sin_addr.s_addr    
= inet_addr( RemoteHostIP );
    
//sServerAddr->sin_addr.s_addr = INADDR_ANY;
    sServerAddr.sin_port           = htons( RemoteHostPort );

#ifdef MS_SOCKET
    
if((SocketId=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))<0)
#else
    
if((SocketId=socket(AF_INET,SOCK_STREAM,0))<0)
#endif
    
{    
        
return -1;
    }

    mylinger.l_onoff  
= 1;
    mylinger.l_linger 
= 0;

    setsockopt(SocketId, SOL_SOCKET, SO_LINGER, 
        (
char *&mylinger,sizeof(struct linger));
#ifndef MS_SOCKET
    sigset(SIGPIPE,SIG_IGN);
#endif

    optval 
= 1;
    setsockopt(SocketId, SOL_SOCKET, SO_KEEPALIVE, 
        (
char *&optval,sizeof(int));

    Result 
= connect(SocketId,(struct sockaddr*)&sServerAddr,sizeof(struct sockaddr_in));
    
    
if( Result != 0 )
    
{    
        shutdown( SocketId,
2 );
#ifdef MS_SOCKET
        ::closesocket(SocketId);
#else
        close( SocketId );
#endif
        userlog(
"function connect error, return Value is %d",Result);
        
return -1;
    }

    
    
//
    
// Format the HTTP request
    
//
    
// request buffer 
    char szGetBuffer[8096];
    
// input http command into request buffer and format it;
    sprintf(szGetBuffer,"POST %s HTTP/1.0\r\n""Content-Type:text/html;charset=gb2312;\r\n""Content-Length:%u\r\n"
                
"\r\n"
                
"%s"
                
"\r\n\0",
            lpURL, strlen(lpExtraHeaderInfo), lpExtraHeaderInfo);

    
//发送Post请求
    Result = send(SocketId, szGetBuffer, strlen(szGetBuffer), 0);
    
    userlog(
" In Post function , the szGetBuffer is %s",szGetBuffer);

    
if( Result == -1 )
    
{    
        shutdown( SocketId,
2 );
#ifdef MS_SOCKET
        ::closesocket(SocketId);
#else
        close( SocketId );
#endif
        userlog(
"function send error, return Value is %d",Result);
        
return -1;
    }

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


    
// recv http header
    string header;
    
int headerLength = RecvHttpHeader(SocketId,header);
    
if(headerLength > 0)
    
{
        
int contentLength = FindContentLength(header);

        
if(contentLength > 0)
        
{
            
string strBody;

            RecvHttpBody(SocketId,strBody,contentLength);
            userlog(
"the sRecvBuf is %s",strBody.c_str());
        }


    }

    
else
    
{
            userlog(
"the return string is not http protptype");
    }


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


int FindContentLength(string header)
{
    std::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);
        userlog(contentString.c_str());
        pos 
= contentString.find(":",0);
        
        
string strLength = contentString.substr(pos + 1);

        
return (int)std::strtol(strLength.c_str(),NULL,10);
    }

    
return 0;
}



int RecvHttpHeader(int socket, string& header)
{
    header.clear();

    
char chRecvBuf[1];
    
    
char endBytes[] = 13101310 };
    
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 
        

抱歉!评论已关闭.