使用Winsock获取随机/奇怪的数据

时间:2014-05-31 23:07:55

标签: c++ winsock winsock2

我是新手使用Winsock并了解它可以做什么我创建了一个快速的HTTP客户端(不是真的)只需要一个网站的索引页面。但是,在尝试读取从服务器接收的数据时,这不是我所期望的。这是一些示例输出:

ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ̤÷

当连接到我尝试的任何网站时会发生这种情况,我试图输出recvbuf的内容,其中收到的数据应该存储。这是通常从winsock返回数据的方式吗?另外,我不认为这是我的代码,因为我没有收到任何错误。我很确定这是正常的,我只是错过了一步,但搜索没有发现任何东西,所以我在这里问。

编辑:抱歉,我不相信我忘了我的代码:

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include "stdafx.h"
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <iostream>

#pragma comment(lib, "Ws2_32.lib")

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    addrinfo *result, *ptr, hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;

WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
iResult = getaddrinfo("google.com", "80", &hints, &result);
if (iResult != 0) {
    cout << "Error in getaddrinfo()!\n";
    cin.get();
    return 1;
} else {
    cout << "Success!\n";
}

SOCKET ConnectSocket = INVALID_SOCKET;

ptr = result;

ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);

iResult = connect(ConnectSocket, ptr->ai_addr, int(ptr->ai_addrlen));

freeaddrinfo(result);

int recvbuflen = 512;
char *sendbuf = "GET / http/1.1";
char recvbuf[512];

send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0);

shutdown(ConnectSocket, SD_SEND);

do {
    iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
    cout << recvbuf << endl;
} while (iResult > 0);

cin.get();
return 0;
}

2 个答案:

答案 0 :(得分:1)

您的HTTP请求有问题。阅读RFC 2616。试试这个:

char *sendbuf = "GET / HTTP/1.1\r\nHost: google.com\r\n\r\n";

这是 HTTP 1.1 请求所需的最低

由于您正在关闭套接字的发送部分,因此您还应该包含Connection: close标头,因为您不会为后续请求重用套接字:

char *sendbuf = "GET / HTTP/1.1\r\nHost: google.com\r\nConnection: close\r\n\r\n";

如果您发送的是 HTTP 1.0 请求,则可以省略HostConnection标题(Host未在1.0中使用,{{ 1}}是1.0)中的默认行为:

close

话虽如此,您的阅读循环过于简单,而不是应该如何读取HTTP响应。您需要逐行读取HTTP标头,直到遇到空行,然后根据标头告诉您的读取方式解析标头并读取HTTP主体的其余部分(如果有)(请参阅{{3}有关细节)。请参阅我为正确的工作流程编写的RFC 2616 Section 4.4

答案 1 :(得分:-1)

我对&#34; GET / http / 1.1&#34;知之甚少,但Google使用HTTPS。

所以我更换&#34; google.com&#34;通过&#34; web.mit.edu&#34;,并转到刷新&#34; http://web.mit.edu/&#34;。

它真的有用。