一个HTTP.二进制POST和HTTP指定长度接收的C++实现
// 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[] = { 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();
}
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();
}
//
#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[] = { 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();
}
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();
}
QQ:273352165
evlon#126.com
转载请注明出处。