http client c++ 代码
为何手写
### 很多c ,c++ 的获取http协议内容,get或者post 的时候,会犯难,是自己写还是使用现成的库,动辄编译一个库是比较消耗时间的,
能自己手写就不要随便编译库了。
#include
#include
#ifdef _WIN32
#include
#endif
using namespace std;
int contentlen_get(char * pos, char * end)
{
char buf[16];
char * t = pos;
while (*(t) == ' ')
t++;
char * e = t;
int i = 0;
while ((*e) != '\r')
{
buf[i++] = *e;
e++;
if (i > 14)
return -1;
}
buf[i] = '\0';
return atoi(buf);
}
class http_connect
{
public:
http_connect::http_connect()
{
#ifdef _WIN32
WSADATA wsa = { 0 };
WSAStartup(MAKEWORD(2, 2), &wsa);
#endif
}
http_connect::~http_connect()
{
WSACleanup();
}
int http_connect::socketHttp(const char* host, unsigned short port,
const char *request,char *buf, int buflen)
{
SOCKET sockfd;
struct sockaddr_in address;
struct hostent *server;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
address.sin_family = AF_INET;
address.sin_port = htons(port);
server = gethostbyname(host);
memcpy((char *)&address.sin_addr.s_addr, (char*)server->h_addr, server->h_length);
#ifdef _WIN32
int ret = 0;
struct timeval timeout = { 2,0 };
setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(struct timeval));
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval));
#endif
if (-1 == connect(sockfd, (struct sockaddr *)&address, sizeof(address))) {
#ifdef _WIN32
closesocket(sockfd);
#endif
printf("connection error!\n");
return -1;
}
#ifdef WIN32
int iRes = send(sockfd, request, (int)strlen(request), 0);
if (iRes == SOCKET_ERROR) {
printf("send failed: %d\n", WSAGetLastError());
closesocket(sockfd);
return -1;
}
#else
struct timeval timeout = { 2,0 };
int ret = setsockopt(sock_fd, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeout, sizeof(timeout));
int ret = setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
write(sockfd, request, strlen(request));
#endif
int offset = 0;
int rc = 0;
do {
buflen = buflen - offset;
if (buflen > 0)
{
#ifdef WIN32
rc = recv(sockfd, buf + offset, buflen, MSG_WAITALL);
#else
rc = read(sockfd, buf + offset, 1024);
#endif
}
if (rc > 0) {
offset += rc;
printf("Bytes received: %d\n", rc);
}
else if (rc == 0)
{
printf("Connection closed\n");
}
else
{
printf("recv failed: %d\n", rc);
}
} while (rc > 0);
#ifdef WIN32
closesocket(sockfd);
#else
close(sockfd);
#endif
buf[offset] = 0;
const char * content_length = strstr(buf, "Content-Length:");
const char * pos = strstr(buf, "\r\n\r\n");
if (content_length == NULL || pos == NULL)
{
return -1;
}
else
{
content_length += 15;
int len = contentlen_get(" 8\r\n", NULL);
if (len <= 0)
{
return -1;
}
pos += 4;
strncpy(buf, pos, len);
buf[len] = '\0';
printf("%s\n", pos);
}
return 0;
#if 0
size_t r = _data.rfind("\r\n\r\n");
cout << "r is " << r << endl;
string re = _data.substr(409 + 4);
cout << "the re is " << re << endl;
#endif
}
int http_connect::postData(const char* host,
unsigned short port,
const char* path,
const char* post_content,char *buf, int buflen)
{
std::stringstream stream;
stream << "POST " << path;
stream << " HTTP/1.0\r\n";
stream << "Host: " << host << "\r\n";
stream << "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3\r\n";
stream << "Content-Type:application/json\r\n";
stream << "Content-Length:" << strlen(post_content) << "\r\n";
stream << "Connection:close\r\n\r\n";
stream << post_content;
return socketHttp(host, port, stream.str().c_str(),buf, buflen);
}
int http_connect::getData(const char* host, unsigned short port,
const char* path,
const char* get_content,char * buf, int buflen)
{
std::stringstream stream;
if (get_content != NULL && strlen(get_content) > 0)
stream << "GET " << path << "?" << get_content;
else
stream << "GET " << path;
stream << " HTTP/1.0\r\n";
stream << "Host: " << host << "\r\n";
stream << "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3\r\n";
stream << "Connection:close\r\n\r\n";
return socketHttp(host, port, stream.str().c_str(),buf,buflen);
}
};
以上为基本class ,如何调用,比较简单
int main(int argc, char* argv[])
{
char buffer[10240];
http_connect hc;
if (hc.getData("127.0.0.1", 80, "/test", NULL, buffer, 10240) == 0)
{
printf("receive json:");
printf(buffer);
}
else
{
printf("连接错误");
}
return 0;
}