天天看點

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);
};      

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 <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", 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編碼顯示的。

轉載于:https://www.cnblogs.com/icez/p/3983240.html