HTTP
#include<iostream>
#include<sys/socket.h>
#include<unistd.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<cstring>
#include<ctype.h>
#include<string>
#include<netdb.h>
using namespace std;
//ip地址
string IP;
//域名,主机名称
string HOST = "hcl.baidu.com";
//请求资源路径
string PATH = "index.html";
//端口
const u_short PORT = 80;
//错误处理
void error(const char* msg) noexcept
{
cout << msg << endl;
}
int main(int args,char* argv[],char* envp[])
{
//通过主机名解析ip地址
hostent* host = gethostbyname(HOST.c_str());
if (host == nullptr)
{
error("get host infomation failed !");
}
//解析获取一个主机名对应的ip地址
in_addr** addr_list = reinterpret_cast<in_addr**>(host->h_addr_list);
for (size_t i = 0; addr_list[i] != nullptr; ++i)
{
//把网络字节序转化为可识别的字节序列
IP = inet_ntoa(*addr_list[i]);
break;
}
if(IP.size() == 0)
{
error("解析ip地址错误 !");
}
//http请求头
string request = "GET /" + PATH + " HTTP/1.1\r\nHost: " + HOST + "\r\nConnect: close\r\n\r\n";
//创建套接字
int server = socket(AF_INET,SOCK_STREAM,0);
if(server < 0)
{
error("create socket failed !");
}
//为套接字绑定信息
sockaddr_in addr;
memset(&addr,0,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
if(inet_pton(AF_INET,IP.c_str(),&addr.sin_addr) < 0)
{
error("translate ip address failed !");
}
//主动发起tcp连接
if(connect(server,(sockaddr*)&addr,sizeof(addr)) == 0)
{
int res = send(server,request.c_str(),request.size(),0);
if(res < 0)
{
error("send erro !");
}
//缓冲区
char buffer[2048];
bzero(buffer,sizeof(buffer));
//recv接收来自socket缓冲区的数据,当缓冲区没有数据可取时,recv会一直处于阻塞状态,直到缓冲区至少又一个字节数据可读取,或者对端关闭,并读取所有数据后返回.
//网络协议规定一次传输最大字节为1500字节
//可能缓冲器中存放着超过1500字节的数据,需要循环读取直到读取全部数据
while(true)
{
res = recv(server,buffer,sizeof(buffer) - 1,0);
if(res > 0)
{
buffer[res] = '\0';
cout << buffer;
}
else
{
break;
}
}
}
else
{
error("connect failed !");
}
close(server);
return 0;
}
CC = g++
CFLAG = -w -std=c++2a -O2 -lpthread
FILES = ./main
all : $(FILES)
clean :
rm -f $(FILES)
main : main.cpp
$(CC) main.cpp -o main $(CFLAG)
HTTPS
#include <netdb.h>
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <openssl/ssl.h>
#include <openssl/bio.h>
#include <openssl/err.h>
using namespace std;
//ip地址
string IP;
//主机名,域名
string HOST = "hcl.baidu.com";
//端口号
const u_short PORT = 443;
//GET请求文件路径
const string PATH = "index.html";
//错误处理
void error(const char* msg) noexcept
{
cout << msg << endl;
}
//1.创建套接字,为套接字绑定信息
//2.和服务器建立tcp连接
//3.初始化SSL库,将ssl和套接字绑定在一起
//4.进行tls握手
//5.使用ssl库的send和recv函数进行发送和接受消息
int main()
{
//通过主机名解析ip地址
hostent* host = gethostbyname(HOST.c_str());
if (host == nullptr)
{
error("get host infomation failed !");
}
//解析获取一个主机名对应的ip地址
in_addr** addr_list = reinterpret_cast<in_addr**>(host->h_addr_list);
for (size_t i = 0; addr_list[i] != nullptr; ++i)
{
//把网络字节序转化为可识别的字节序列
IP = inet_ntoa(*addr_list[i]);
break;
}
// 初始化OpenSSL
SSL_library_init();
ERR_load_BIO_strings();
SSL_load_error_strings();
// 创建SSL上下文
SSL_CTX* ctx = SSL_CTX_new(TLSv1_2_client_method());
if(!ctx)
{
error("create SSL_CTX failed !");
}
// 创建TCP套接字
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0)
{
error("create socket failed !");
}
// 设置服务器地址,协议,端口信息
sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
if(inet_pton(AF_INET, IP.c_str(), &(server_addr.sin_addr)) < 0)
{
error("translate ip address failed !");
}
// 连接服务器,首先建立tcp链接
if(connect(sockfd, (sockaddr*)&server_addr, sizeof(server_addr)) < 0)
{
error("connect server failed !");
}
// 创建SSL对象
SSL* ssl = SSL_new(ctx);
if(!ssl)
{
error("create SSL* failed !");
}
//将ssl对象和套接字绑定
if(SSL_set_fd(ssl, sockfd) == 0)
{
error("failed to bind socket with ssl !");
}
// 然后建立SSL连接
if(SSL_connect(ssl) <= 0)
{
error("failed to build ssl connect !");
}
// 发送HTTPS请求
string request = "GET /" + PATH + " HTTP/1.1\r\nHost: " + HOST + "\r\nConnection: close\r\n\r\n";
int len = SSL_write(ssl, request.c_str(), request.size() + 1);
if(len <= 0)
{
error("send failed !");
}
// 接收并打印服务器https响应
string file;
char buffer[4096];
memset(buffer,0,sizeof(buffer));
while ((len = SSL_read(ssl, buffer, sizeof(buffer) - 1)) > 0)
{
buffer[len] = '\0';
file += buffer;
}
cout << file;
// 关闭连接
SSL_shutdown(ssl);
SSL_free(ssl);
close(sockfd);
SSL_CTX_free(ctx);
return 0;
}
CC = g++
CFLAG = -w -std=c++2a -O2 -lpthread -lssl -lcrypto
FILES = ./main
all : $(FILES)
clean :
rm -f $(FILES)
main : main.cpp
$(CC) main.cpp -o main $(CFLAG)
Comments NOTHING