c - 当我想通过 Winsock 下载文件时,我收到了来自服务器的错误请求
问题描述
我想下载一个带有套接字的 PDF 文件。我从服务器收到“400 Bad Request”错误,说“普通 HTTP 请求已发送到 HTTPS 端口”,如下图所示(我将其作为 HTML 页面打开):
我将端口从 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");
}
}
解决方案
您需要一个 TLS 库,以便您可以向服务器发送http 。
这太大了,无法在 C 中发布答案,但由于您使用的是 Winsock,您不妨使用内置的schannel。
推荐阅读
- javascript - 在javascript中将颜色代码转换为十六进制代码
- android - 无法将数据插入或检索到实体在 kotlin 中有列表的房间
- python - 如何并行下载多个数据集?
- node.js - 如何在 Mongoose 中创建 2dsphere 索引?
- java - 按字母顺序实现双链表
- excel - 使用 vba 将过滤器数据复制到同一工作表
- php - 可点击元素靠得太近,内容比 Google 搜索控制台中的屏幕宽
- scala - scala数据集中出现频率最高的值
- android - 由于缺少 FTS rowid 列,房间迁移测试失败
- css - 为什么 div 继承父属性然后继承类属性?