socket编程实现HTTP请求

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

socket编程实现HTTP请求_第1张图片

 

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

socket编程实现HTTP请求_第2张图片

 

代码截图:

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

 

socket编程实现HTTP请求_第3张图片

下面是代码实现:

 

//mySocket.h头文件
#include 
#include 
#include 
#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);
};
View Code

 

//mySocket.c源码文件
 1 #include "mySocket.h" 
 2 
 3 //只是对Socket中使用TCP协议的封装
 4 
 5 int MySocket::InitClient(SOCKET *sock, string ip, int port)
 6 {
 7     WSADATA wsaData;//初始化wsaData
 8     if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
 9     {
10         return -1;
11     }
12 
13     //创建套接字
14     if ((*sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
15     {
16         WSACleanup();
17         return -1;
18     }
19 
20     struct sockaddr_in serverAddr;
21     serverAddr.sin_family = AF_INET;
22     serverAddr.sin_port = htons(port);
23     serverAddr.sin_addr.s_addr = inet_addr(ip.c_str());
24 
25     if (connect(*sock, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
26     {
27         return -1;
28     }
29 
30     return 0;
31 }
32 
33 int MySocket::CloseMySocket(SOCKET *sock)
34 {
35     if (closesocket(*sock) == SOCKET_ERROR)
36     {
37         WSACleanup();
38         return -1;
39     }
40     return 0 ;
41 }
42 
43 int MySocket::RecvData(SOCKET sock, string &data)
44 {
45     int bufLen = 255;
46     char buf[256];
47     int recvLen= 0;
48     int iResult;
49     buf[bufLen] = '\0';
50     while (true)
51     {
52         iResult = recv(sock, buf, bufLen, 0);
53         if (iResult < 0)
54         {
55             data = "";
56             return -1;
57         }
58 
59         recvLen += iResult;
60 
61         if (iResult == 0)
62         {
63             return recvLen;
64         }
65 
66         if (iResult == bufLen)
67         {
68             data += buf;
69             ZeroMemory(buf, bufLen);
70             continue;
71         }
72         if (iResult > 0 && iResult < bufLen)
73         {
74             data += buf;
75             return recvLen;
76         }
77     }
78 }
79 
80 int MySocket::SendData(SOCKET sock, const string data)
81 {
82     int iResult = send(sock, data.c_str(), data.length(), 0);
83     if (iResult == SOCKET_ERROR) {
84         MySocket::CloseMySocket(&sock);
85         WSACleanup();
86         return -1;
87     }
88 
89     return 0;
90 }
View Code
//main函数
#include 
#include 
#include 
#include "mySocket.h"
using namespace std;
int main()
{
    SOCKET clientSock;
    string str;
    int iResult;
    if (MySocket::InitClient(&clientSock, "42.121.254.229", 80) == -1)//主机IP地址+端口号
    {
        printf("连接失败\n");
        return -1;
    }
    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 == -1)
    {
        printf("发送数据失败\n");
        return -1;
    }
    iResult = MySocket::RecvData(clientSock, str);
    
    if (iResult  == -1)
    {
        printf("接受数据失败\n");
        return -1;
    }
    printf("----接受数据长度:%d----\n", iResult);
    printf(str.c_str());
    MySocket::CloseMySocket(&clientSock);
    return 0;
}

 

 

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

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

 

你可能感兴趣的:(socket编程实现HTTP请求)