[英]simple HTTP client c recv() blocks
我嘗試用c編寫簡單的HTTP客戶端,當我執行程序一段時間后,我有時從網站上獲取數據。 特定的recv()塊,並關閉連接。 解決這個問題的最佳方法是什么? 我仍然想獲取網站數據。
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協議概念並將其發送到在此模板中嘗試過的每個URL:sendbuf =“ GET / [url path] HTTP 1.0 / r / nHost:[www.pure_url.com] / r / n / r / n“
編輯:我已經嘗試過[DaSourcerer建議],更改為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);
這個想法沒有幫助。
我認為您的超時時間太嚴格。 您發送的標頭還將激發服務器等待進一步的輸入。 嘗試這個:
GET /path HTTP/1.1
Host: example.com
Connection: close
還需要提及的是Host
是HTTP / 1.1中引入的標頭。 在HTTP / 1.0中沒有意義。 您可能還會對RFC 7230的3.3.3節感興趣,因為您幾乎肯定會在HTTP / 1.1中遇到塊編碼的消息。 不過,請不要擔心:可以使用簡單的狀態機進行解析。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.