socket编程实现HTTP请求

利用c++语言+socket实现HTTP请求,请求获得的数据效果图如下:

socket编程实现HTTP请求

HTTP协议的下一层是TCP,根据HTTP协议只需要利用TCP发送下面的数据到达目标主机,目标主机就会发送相应的数据到客户端。

socket编程实现HTTP请求

代码截图:

特别注意每一行末的\r\n

socket编程实现HTTP请求

下面是代码实现:

//mySocket.h头文件
#include <Winsock2.h>
#include <Windows.h>
#include <Ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
#include <string>
using namespace std; //只是对Socket中使用TCP协议的一种封装
class MySocket{
public:
static int InitClient(SOCKET *sock, string ip, int port);
static int CloseMySocket(SOCKET *Sock);
static int SendData(SOCKET sock, const string data);
static int RecvData(SOCKET sock, string &data);
};
//mySocket.c源码文件
 #include "mySocket.h" 

 //只是对Socket中使用TCP协议的封装

 int MySocket::InitClient(SOCKET *sock, string ip, int port)
{
WSADATA wsaData;//初始化wsaData
if (WSAStartup(MAKEWORD(, ), &wsaData) != )
{
return -;
} //创建套接字
if ((*sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
WSACleanup();
return -;
} struct sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(port);
serverAddr.sin_addr.s_addr = inet_addr(ip.c_str()); if (connect(*sock, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
{
return -;
} return ;
} int MySocket::CloseMySocket(SOCKET *sock)
{
if (closesocket(*sock) == SOCKET_ERROR)
{
WSACleanup();
return -;
}
return ;
} int MySocket::RecvData(SOCKET sock, string &data)
{
int bufLen = ;
char buf[];
int recvLen= ;
int iResult;
buf[bufLen] = '\0';
while (true)
{
iResult = recv(sock, buf, bufLen, );
if (iResult < )
{
data = "";
return -;
} recvLen += iResult; if (iResult == )
{
return recvLen;
} if (iResult == bufLen)
{
data += buf;
ZeroMemory(buf, bufLen);
continue;
}
if (iResult > && iResult < bufLen)
{
data += buf;
return recvLen;
}
}
} int MySocket::SendData(SOCKET sock, const string data)
{
int iResult = send(sock, data.c_str(), data.length(), );
if (iResult == SOCKET_ERROR) {
MySocket::CloseMySocket(&sock);
WSACleanup();
return -;
} return ;
}
//main函数
#include <stdio.h>
#include <iostream>
#include<time.h>
#include "mySocket.h"
using namespace std;
int main()
{
SOCKET clientSock;
string str;
int iResult;
if (MySocket::InitClient(&clientSock, "42.121.254.229", ) == -)//主机IP地址+端口号
{
printf("连接失败\n");
return -;
}
string head = "GET / HTTP/1.1\r\n";
head.append("Host: m.cnblogs.com\r\n");//请求的域名
head.append("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n");
head.append("User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36\r\n");
head.append("Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n");
head.append("Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7");
head.append("Accept-Encoding: gzip,deflate\r\n");
head.append("\r\n");//表明请求头结束了
iResult = MySocket::SendData(clientSock, head);
if (iResult == -)
{
printf("发送数据失败\n");
return -;
}
iResult = MySocket::RecvData(clientSock, str); if (iResult == -)
{
printf("接受数据失败\n");
return -;
}
printf("----接受数据长度:%d----\n", iResult);
printf(str.c_str());
MySocket::CloseMySocket(&clientSock);
return ;
}

如果请求别的网站,有可能连返回的数据全部是乱码,那就是网站启用了gzip压缩了。

图中截图中文乱码,是因为返回的是UTF-8编码的字符,控制台默认是已GBK编码显示的。

上一篇:Linux设置:环境变量


下一篇:推荐一款有趣的APP-种子习惯