Winsock 数据不是从 IP 检索的,而是从普通 URL 检索的
Winsock data is not retrieved from an IP, but it's retrieved from a normal URL
我有一个用Winsock获取网页内容的函数,我遇到的问题是,我在指定URL时收到页面,而在用IP 替换它时却什么都得不到
这是有效的:get_Website("www.google.com"(;
这不是:get_Website("100.111.33.77"(;
// Function
void get_Website(string url ){
WSADATA wsaData;
SOCKET Socket;
SOCKADDR_IN SockAddr;
int lineCount=0;
int rowCount=0;
struct hostent *host;
string get_http;
get_http = "POST / HTTP/1.1rnHost: " + url + "rnConnection: closernrn";
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0){
cout << "WSAStartup failed.n";
system("pause");
//return 1;
}
Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
host = gethostbyname(url.c_str());
SockAddr.sin_port=htons(80);
SockAddr.sin_family=AF_INET;
SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr);
if(connect(Socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr)) != 0){
cout << "Could not connect";
system("pause");
//return 1;
}
send(Socket,get_http.c_str(), strlen(get_http.c_str()),0 );
int nDataLength;
while ((nDataLength = recv(Socket,buffer,10000,0)) > 0){
int i = 0;
while (buffer[i] >= 32 || buffer[i] == 'n' || buffer[i] == 'r'){
website_HTML+=buffer[i];
i += 1;
}
}
closesocket(Socket);
WSACleanup();
}
IP地址不是主机名,因此不要使用gethostbyname()
来解析IP地址。首先检查输入是否为IP,如果不是,则将其解析为主机名。在您的示例中,由于您使用的是AF_INET
,因此可以简单地使用inet_addr()
进行检查,例如:
SockAddr.sin_addr.s_addr = inet_addr(url.c_str());
if (Sockaddr.sin_addr.s_addr == INADDR_NONE)
{
host = gethostbyname(url.c_str());
if (!host) {
// could not resolve...
return;
}
if (host->h_addrtype != AF_INET) {
// did not resolve to IPv4...
return;
}
Sockaddr.sin_addr.s_addr = *reinterpret_cast<u_long*>(host->h_addr);
}
请注意,一个主机名可以解析为多个IP地址,因此您应该遍历整个host->h_addr_list
,尝试将connect()
循环到每个IP,直到其中一个成功为止。
不过,您确实应该使用getaddrinfo()
,因为gethostbyname()
已被弃用,例如:
addrinfo hints = {};
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
addrinfo *result = NULL;
if (getaddrinfo(url.c_str(), "80", &hints, &result) != 0) {
// could not resolve...
return;
}
bool connected = false;
for(addrinfo *addr = result; (addr != NULL) && (!connected); addr = addr->ai_next) {
connected = (connect(Socket, addr->ai_addr, addr->ai_addrlen) == 0);
}
freeaddrinfo(result);
if (!connected) {
// could not connect...
return;
}
相关文章:
- 使用VerQueryValue检索应用程序的文件描述
- 是否可以从格式字符串中检索"width"
- 使用 pqxx 将 std::vector 存储在 postgresql 中,并从数据库中检索它
- 如何使用url确定网站协议
- 下载URL中的所有文件
- 使用libcurl提交批量url的正确BING Api POST url是什么
- 如何在QByteArray中放置和检索位字段而不会感到痛苦?
- 如何在Qt中从数据库中检索二进制数据?
- 将所有 URL 组织在类中的一个位置
- 如何从C++代码中检索 QML 的文本字段中的文本?
- 从 opencv c++ 中的矢量中检索固定的帧数
- 如何在不等待检索的情况下获取C++中的内存位置?
- 如何在 QTreeWidget 中检索特定项目的 mimeData?
- C++从字符串中检索几行
- 从 C++ 中的 URL 获取结果
- 在数据库中插入和检索矩阵
- 两个垫子的 OpenCV 数据是相同的,但使用 Mat::at 检索时的值已损坏
- 使用 const char* 键映射 C++ 检索空值
- C++ libcurl - 无法从 URL 检索整个 html 内容
- Winsock 数据不是从 IP 检索的,而是从普通 URL 检索的