[网络]url解码,从网址转化为ip
我们在学习网络时,底层代码中往往需要指定对应的ip进行通信,而网络上的资源大多是以网址的形式进行传输的,那么如何从网址变为ip呢
DNS
首先我们知道一个网址,比如说baidu.com,我们要把它变为ip,首先会检查本地缓存(如浏览器缓存或操作系统缓存)中是否已经存在该域名的IP地址。如果存在,直接使用缓存的IP地址,无需进一步查询。
如果本地缓存没有会递归的向上层查询,DNS(域名系统,Domain Name System)就是对应的上层服务器
代码
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <cstring>
// 函数:解析域名并获取IP地址和端口号
std::pair<std::string, int> resolveUrl(const std::string &url)
{
// 默认端口
int port = 443; // HTTPS 默认端口
if (url.find("http://") == 0)
{
port = 80; // HTTP 默认端口
}
// 提取域名
std::string domain = url;
if (domain.find("http://") == 0)
{
domain = domain.substr(7); // 去掉 "http://"
}
else if (domain.find("https://") == 0)
{
domain = domain.substr(8); // 去掉 "https://"
}
// 检查是否有自定义端口
size_t colonPos = domain.find(':');
if (colonPos != std::string::npos)
{
port = std::stoi(domain.substr(colonPos + 1));
domain = domain.substr(0, colonPos);
}
// 使用getaddrinfo解析域名
struct addrinfo hints, *res;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET; // IPv4
hints.ai_socktype = SOCK_STREAM;
int status;
if ((status = getaddrinfo(domain.c_str(), NULL, &hints, &res)) != 0)
{
std::cerr << "getaddrinfo error: " << gai_strerror(status) << std::endl;
return {"", -1};
}
// 获取IP地址
char ipStr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &((struct sockaddr_in *)res->ai_addr)->sin_addr, ipStr, INET_ADDRSTRLEN);
freeaddrinfo(res); // 释放资源
return {ipStr, port};
}
int main(int argc, char **argv)
{
std::string str_url;
if (argc == 2)
{
str_url = argv[1];
}
else
{
std::cerr << "参数错误" << std::endl;
exit(0);
}
auto[ip,port] = resolveUrl(str_url);
std::cout << "Get a Url : " << str_url << std::endl;
printf("Url to be ip+port %s:%d\n",ip.c_str(),port);
return 0;
}
测试
可以通过对照pin指令来判断结果是否正确