zoukankan
html css js c++ java
一个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();
}
QQ:273352165 evlon#126.com 转载请注明出处。
查看全文
相关阅读:
c++ stringstream
c语言中字符串数组初始化的一点总结&& c++访问控制的三种方式
Leetcode 2. Add Two Numbers(medium)
面试题---反转一个字符串
编程题---在数组中取一个位置,让这个位置之前的数的和与之后的和的差绝对值最小
美团面试准备
Leetcode 101. Symmetric Tree(easy)
Leetcode 665. Non-decreasing Array(Easy)
617. Merge Two Binary Trees(Easy)
423. Reconstruct Original Digits from English(Medium)
原文地址:https://www.cnblogs.com/evlon/p/853145.html
最新文章
Web从入门到放弃<1>
微积分与概率统计---生命动力学的建模
剑指Offer——丑数
剑指Offer——把数组排成最小的数
剑指Offer——整数中1出现的次数
剑指Offer——连续子数组的最大和
剑指Offer——最小的K个数
剑指Offer——数组中出现次数超过一半的数字
剑指Offer——字符串的排列
剑指Offer——二叉搜索树与双向链表
热门文章
剑指Offer——复杂链表的复制
剑指Offer——树的子结构二叉树中和为某一值的路径
599. Minimum Index Sum of Two Lists(easy)
Leetcode 88. Merge Sorted Array(easy)
646. Maximum Length of Pair Chain(medium)
搜狗面试
美团面试
Leetcode 561. Array Partition I(easy)
左值引用和右值引用
Leetcode 26. Remove Duplicates from Sorted Array (easy)
Copyright © 2011-2022 走看看