我尝试用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协议概念并发送到我在这个模板中尝试过的每个网址: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);
这个想法没有帮助。
答案 0 :(得分:0)
我认为你的超时太严格了。您发送的标头也会激发服务器等待进一步输入。试试这个:
GET /path HTTP/1.1
Host: example.com
Connection: close
还提到Host
是HTTP / 1.1中引入的标头。它在HTTP / 1.0中没有任何意义。您可能也对RFC 7230, section 3.3.3感兴趣,因为您几乎肯定会遇到HTTP / 1.1中的块编码消息。不过不用担心:它可以用简单的状态机解析。