利用c++語言+socket實作HTTP請求,請求獲得的資料效果圖如下:
HTTP協定的下一層是TCP,根據HTTP協定隻需要利用TCP發送下面的資料到達目标主機,目标主機就會發送相應的資料到用戶端。
代碼截圖:
特别注意每一行末的\r\n
下面是代碼實作:
//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