首页 > 解决方案 > 当我想通过 Winsock 下载文件时,我收到了来自服务器的错误请求

问题描述

我想下载一个带有套接字的 PDF 文件。我从服务器收到“400 Bad Request”错误,说“普通 HTTP 请求已发送到 HTTPS 端口”,如下图所示(我将其作为 HTML 页面打开):

image_bad_request_server

我将端口从 443 更改为 80,但我没有得到服务器的响应。file.pdf当我将端口更改为 80 时,我什么都没有。

这是我的控制台输出:

通过socket 268连接到服务器

发送字节数:109
收到的字节数:0

接收字节 = 100
总数据 = 100Bytes 接收:0

接收字节 = 100
总数据 = 200Bytes 收到:0

接收字节 = 100
总数据 = 300Bytes 收到:0

接收字节 = 100
总数据 = 400Bytes 接收:0

接收字节 = 30
总数据 = 430连接已关闭

接收字节 = 0
总数据 = 430 收到回复

这是我的代码。我打开套接字并连接到服务器,但我没有收到文件:

WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
    wprintf(L"WSAStartup function failed with error: %d\n", iResult);
    return 1;
}

sockaddr_in Serv_Addr;

//intialisation
struct addrinfo* result = NULL;
struct addrinfo hints;
ZeroMemory(&hints, sizeof(hints));

//socket configuration
SOCKET TcpClientSocket = -1;
int ret = 0;
TcpClientSocket = socket(AF_INET, SOCK_STREAM, 0);
if (TcpClientSocket == INVALID_SOCKET) {
    wprintf(L"socket function failed with error: %ld\n", WSAGetLastError());
    WSACleanup();
    return 1;
}
Serv_Addr.sin_family = AF_INET;
Serv_Addr.sin_port = htons(443);
Serv_Addr.sin_addr.s_addr = inet_pton(AF_INET, "47.88.2.145", &Serv_Addr.sin_addr); //connect to www.axmag.com, link pdf file http://www.axmag.com/download/pdfurl-guide.pdf
printf("Connected to server via socket %u\n", TcpClientSocket);

//connection
iResult = -1;
iResult = connect(TcpClientSocket, (sockaddr*)& Serv_Addr, sizeof(Serv_Addr));
printf("%d", iResult);
if (iResult == SOCKET_ERROR) {
    wprintf(L"connect function failed with error: %ld\n", WSAGetLastError());
    iResult = closesocket(TcpClientSocket);
    if (iResult == SOCKET_ERROR)
        wprintf(L"closesocket function failed with error: %ld\n", WSAGetLastError());
    WSACleanup();
    return 1;
}

// send request
const char* message;
message = "GET /download/pdfurl-guide.pdf HTTP/1.1\r\nHost: www.axmag.com\r\n\r\n Connection: keep-alive\r\n\r\n Keep-Alive: 300\r\n";

// test send succeded

iResult = send(TcpClientSocket, message, strlen(message), 0);
if (iResult == SOCKET_ERROR)
{
    printf("send failed: %d\n", WSAGetLastError());
    closesocket(TcpClientSocket);
    WSACleanup();
    return 1;
}
printf("Bytes Sent: %ld\n", iResult);

// shutdown the connection for sending since no more data will be sent
// the client can still use the ConnectSocket for receiving data
iResult = shutdown(TcpClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
    printf("shutdown failed: %d\n", WSAGetLastError());
    closesocket(TcpClientSocket);
    WSACleanup();
    return 1;
}

FILE* stream;
fopen_s(&stream, "1.html", "w+");   
/////receive response from server
int totalData = 0, received_data = 0;
do
{
    char server_reply[100];
    received_data = recv(TcpClientSocket, server_reply, sizeof server_reply, 0);

    if (received_data > 0)
        printf("Bytes received: %d\n", iResult);
    else if (received_data == 0)
        printf("Connection closed\n");
    else
        printf("recv failed: %d\n", WSAGetLastError());

    totalData += received_data;

    fwrite(server_reply, received_data, 1, stream);

    printf("\nReceived byte  = %d\nTotal data = %d", received_data, totalData);

} while (received_data > 0);

printf("Reply received\n");
if (stream)
{
    if (fclose(stream))
    {
        printf("The file 'crt_fopen.c' was not closed\n");
    }
}

标签: cwindowssocketsbad-request

解决方案


您需要一个 TLS 库,以便您可以向服务器发送http

这太大了,无法在 C 中发布答案,但由于您使用的是 Winsock,您不妨使用内置的schannel


推荐阅读