Winsock 2正在从URL读取文本
Winsock 2 Reading text from a URL
例如,这就是我想要做的:
if (http->Connect("http://pastebin.com/raw/9uL16CyN"))
{
YString data = "";
if (http->ReceiveData(data))
{
std::cout << "Networked data: " << std::endl;
std::cout << data << std::endl;
}
else
std::cout << "Failed to connect to internet.n";
}
我试图从中读取的页面是原始ASCII文本(http://pastebin.com/raw/9uL16CyN)
我希望这能很容易地工作,但显然不是,我一直收到WSA错误:WSAHOST_not_FOUND(11001)
我的连接功能:
bool Http::Connect(YString addr)
{
_socket = Network::CreateConnectSocket(addr, 53); // 53 is the port
return _socket != INVALID_SOCKET;
}
CreateConnectSocket函数:
int iResult;
SOCKET ConnectSocket = INVALID_SOCKET;
// holds address info for socket to connect to
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP; //TCP connection!!!
//resolve server address and port
iResult = getaddrinfo(addr.c_str(), std::to_string(port).c_str(), &hints, &result);
if (iResult != 0)
{
printf("Network::CreateSocket failed with %s as addr, and %i as port.nError code: %i.n", (char*)addr.c_str(), port, iResult);
return INVALID_SOCKET;
}
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("Network::CreateSocket failed with error: %ldn", WSAGetLastError());
return INVALID_SOCKET;
}
// Connect to server.
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR)
{
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
printf("Network::CreateSocket failed the server is down... did not connect.n");
}
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET)
{
printf("Network::CreateSocket failed.n");
return INVALID_SOCKET;
}
u_long iMode = 1;
iResult = ioctlsocket(ConnectSocket, FIONBIO, &iMode);
if (iResult == SOCKET_ERROR)
{
printf("Network::CreateSocket ioctlsocket failed with error: %dn", WSAGetLastError());
closesocket(ConnectSocket);
return INVALID_SOCKET;
}
char value = 1;
setsockopt(ConnectSocket, IPPROTO_TCP, TCP_NODELAY, &value, sizeof(value));
return ConnectSocket;
大部分来自现有来源。
您对Connect()
的调用是错误的。不能将完整URL传递给getaddrinfo()
。您只需要自己传递域名和端口号。顺便说一句,HTTP端口是80,而不是53。
此外,您不会向服务器发送HTTP GET
请求,要求其向您发送文本文档。在您首先发送请求之前,HTTP服务器不会发送响应。
你需要更像这样的东西:
bool Http::Connect(YString addr, int port)
{
_socket = Network::CreateConnectSocket(addr, port);
return _socket != INVALID_SOCKET;
}
if (http->Connect("pastebin.com", 80))
{
YString data = "GET /raw/9uL16CyN HTTP/1.1rn"
"Host: pastebin.comrn"
"Connection: closern"
"rn";
if (http->SendData(data))
{
YString data = "";
if (http->ReceiveData(data))
{
std::cout << "Networked data: " << std::endl;
std::cout << data << std::endl;
}
else
std::cout << "Failed to receive data from internet.n";
}
else
std::cout << "Failed to send request to Pastebin.n";
}
else
std::cout << "Failed to connect to Pastebin.n";
话虽如此,您需要考虑到服务器将用标头来构建响应数据,例如:
GET /raw/9uL16CyN HTTP/1.1
Host: pastebin.com
HTTP/1.1 200 OK
Date: Wed, 23 Dec 2015 00:00:01 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: __cfduid=db6ba4b037d673b67757500aca4e2227b1450828801; expires=Thu, 22-Dec-16 00:00:01 GMT; path=/; domain=.pastebin.com; HttpOnly
X-Powered-By: PHP/5.5.5
Cache-Control: public, max-age=1801
Vary: Accept-Encoding
CF-Cache-Status: HIT
Expires: Wed, 23 Dec 2015 00:30:02 GMT
Server: cloudflare-nginx
CF-RAY: 258fc8a8168a2276-LAX
2a
Text, text, text, text! Some more text! :D
0
因此,假设ReceiveData()
只是返回它接收到的任何内容,那么在您可以单独使用文本文件的内容之前,您必须去掉这些标头,并撤消chunked
编码。请阅读RFC2616(或其后续RFC7230-7235),其中详细概述了HTTP协议。
话虽如此,您应该停止尝试手动实现HTTP(它比您意识到的更复杂),而是使用预先存在的库,就像libcurl
,甚至Microsoft自己的WinInet
或WinHTTP
API一样。让他们为你做繁重的工作。
相关文章:
- 理解boost::asio-async_read在无需读取内容时的行为
- 使用新行和不使用新行读取文件
- 读取文件并输入到矢量中
- 用c++从输入文件中读取另一行
- 读取文件的最后一行并输入到链接列表时出错
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 无法找到/读取配置文件.conf-FileIOException
- 如何使用Luacneneneba API正确读取字符串和表参数
- C++将文本文件中的数据读取到结构数组中
- 正在将csv文件读取为双精度矢量
- 为什么 sscanf 无法从一个字符串中读取uint64_t和字符?
- 为什么在读取文件大小时文件IO速度会发生变化
- 正在读取二进制文件(is_open)
- 当我读取一个大小为 17 mb 的 100 万个 url 文件时,我的程序占用大小为 163 MB
- 使用点云库从C++中的 URL 读取文件,而不是本地文件
- 如何在页面上登录并从中读取URL内容
- Winsock 2正在从URL读取文本
- 无法读取URL主体(JSON)
- xml读取内存 - 未知'url'参数
- 使用QXmlQuery从url读取xml(没有临时文件)