gpt4 book ai didi

c - 简单的 HTTP 客户端 c recv() block

转载 作者:行者123 更新时间:2023-11-30 17:01:31 26 4
gpt4 key购买 nike

我尝试用c编写简单的HTTP客户端,当我执行程序时,有时会从网站获取数据,有时则不会。特定的recv() block ,以及连接关闭。处理这个问题的最好方法是什么?我还想获取网站数据。

ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
if (iResult = getaddrinfo(s1, "http", &hints, &result)) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds

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("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}


iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}

freeaddrinfo(result);

if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}


// Send an initial buffer
iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}

// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}

// Receive until the peer closes the connection

do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen-1, 0);
if ( iResult > 0 ) {
flag = 1;
recvbuf[iResult] = '\0';
printf("%s\n",recvbuf);
}
else if ( iResult == 0 ) {
if(!flag) {
printf("conection close before recv data\n");
} else {
printf("conection close\n");
break;
}
}
else {
printf("recv failed with error: %d\n", WSAGetLastError());
}
} while(iResult>1);


// cleanup
closesocket(ConnectSocket);
WSACleanup();

return 0;

}

我使用了 HTTP 协议(protocol)概念并发送到我在此模板中尝试过的每个网址:sendbuf ="GET/[url path] HTTP 1.0/r/nHost:[www.pure_url.com]/r/n/r/n”

编辑:我尝试过 [DaSourcerer suggest] ,更改为 HTTP/1.1 并添加 Connection: close ,但有时我仍然无法获取数据。

我还补充道:

int tcp_timeout=10000;
unsigned int sz = sizeof(tcp_timeout);
setsockopt(ConnectSocket, SOL_SOCKET, SO_RCVTIMEO,
(char*)&tcp_timeout, sz);

这个想法没有帮助。

最佳答案

我认为你的超时太严格了。您发送的 header 也会促使服务器等待进一步的输入。试试这个:

GET /path HTTP/1.1
Host: example.com
Connection: close

还值得一提的是,Host 是 HTTP/1.1 中引入的 header 。它在 HTTP/1.0 中没有任何意义。您可能还对RFC 7230, section 3.3.3感兴趣因为您几乎肯定会在 HTTP/1.1 中遇到 block 编码消息。不过不用担心:它可以用一个简单的状态机来解析。

关于c - 简单的 HTTP 客户端 c recv() block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36987405/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com