[英]Raw HTTP request with sockets getting “Resource temporarily unavailable”
I am trying to make a raw http request function using sockets in "C++". 我正在尝试使用“ C ++”中的套接字制作原始的http请求功能。 Everything worked good until i saw that i don't have timeout on that function, eg.
一切正常,直到我看到该功能没有超时,例如。 when i do a request on an ip that don't have 80 open, it stays forever, so i decided to make a timeout, there fore instead using
blocking
sockets i started using non-blocking
. 当我在没有打开80的ip上发出请求时,它永远存在,因此我决定进行超时,因此开始使用
blocking
套接字,而我开始使用non-blocking
。 There is that problem started. 问题开始了。 See the code bellow :
参见下面的代码:
CODE : 代码:
size_t raw_http(char *host,char *ip, int port, char *page, char *content, size_t len)
{
int sock;
if(debug_super_http >= 5) puts("AAAA");
// sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock < 0)
{
if(debug_super_http >= 5) puts("BBBB");
//printf("raw_http() ~ socket opening failed.\n");
// exit(1);
return 0;
}
perror("socket");
struct sockaddr_in remote ;
remote.sin_family = AF_INET;
remote.sin_port = htons(port);
remote.sin_addr.s_addr = inet_addr(ip);
fd_set fdset;
struct timeval tv;
fcntl(sock, F_SETFL, O_NONBLOCK);
if(debug_super_http >= 4) puts("CCCC");
perror("socket");
connect(sock,(struct sockaddr*)(&remote),sizeof(struct sockaddr_in));
perror("socket");
FD_ZERO(&fdset);
FD_SET(sock, &fdset);
tv.tv_sec = 10;
tv.tv_usec = 0;
if(select(sock + 1, NULL, &fdset, NULL, &tv) == 1)
{
int so_error;
socklen_t len = sizeof so_error;
getsockopt(sock, SOL_SOCKET, SO_ERROR, &so_error, &len);
if (so_error == 0)
{
//Is connected
if(debug_super_http >= 4) puts("EEEE");
perror("socket");
}
else
{
if(debug_super_http >= 4) puts("FFFF");
perror("socket");
}
}
else
{
if(debug_super_http >= 4) puts("GGGGG");
perror("socket");
}
/*
if(debug_super_http >= 5) puts("33333");
if(inet_pton(AF_INET, ip, (void *)(&(remote.sin_addr.s_addr))) <= 0)
{
//printf("raw_http() ~ inet_pton() failed.\n");
// exit(1);
return 0;
}
remote.sin_port = htons(port);
*/
if(debug_super_http >= 5) puts("44444");
perror("socket");
/*
if(connect(sock, (struct sockaddr *)&remote, sizeof(struct sockaddr)) < 0)
{
if(debug_super_http >= 5) puts("555555");
//printf("raw_http() ~ socket connection failed.\n");
// exit(1);
return 0;
}
*/
if(debug_super_http >= 5) puts("666666");
//build_get_query
char *getpage = page;
if(getpage[0] == '/') getpage = getpage + 1;
char getcmd[4096];
sprintf(getcmd, "GET /%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: %s\r\n\r\n", getpage, host, USERAGENT);
if(debug_super_http >= 5) puts("7777777");
perror("socket");
size_t sent = 0;
while(sent < strlen(getcmd))
{
if(debug_super_http >= 5) puts("8888888");
perror("socket");
ssize_t tmpres = send(sock, getcmd+sent, strlen(getcmd)-sent, 0);
printf("tmpres=[%d]\n",tmpres);
if(tmpres == -1)
{
// printf("raw_http() ~ http get command sending error.\n");
if(debug_super_http >= 5) puts("8.5 8.5 8.5");
// exit(1);
return 0;
}
sent += tmpres;
if(debug_super_http >= 5) puts("8.7 8.7 8.7");
}
if(debug_super_http >= 5) puts("9999999");
perror("socket");
char buf[8192];
memset(buf, 0, 8192);
// initialize html content buffer
memset(content, 0, len);
/*
#if 0
htmlcontent[0] = '\0';
return 0;
#endif
*/
int htmlstart = 0;
printf("recv->[%d]\n",recv(sock, buf, 8192, 0));
fprintf(stderr, "socket() failed: %s\n", strerror(errno));
perror("socket");
while(recv(sock, buf, 8192, MSG_WAITALL) > 0)
{
// if(debug_super_http >= 5) printf(">>> [%s]\n",buf);
if(debug_super_http >= 5) puts("10 10 10");
// receive max 1KB
if(htmlstart == 0)
{
char *ptr = strstr(buf, "\r\n\r\n");
if(ptr != NULL)
{
htmlstart = 1;
ptr += 4;
strcat(content, ptr);
}
}
else
{
strcat(content, buf);
break;
}
memset(buf, 0, 8192);
}
perror("socket");
if(debug_super_http >= 5) printf(">>> CONTENT >>> [%s]\n",content);
if(debug_super_http >= 5) puts("11 11 11");
close(sock);
if(debug_super_http >= 5) puts("12 12 12");
perror("socket");
return strlen(content);
}
I get the request on the http server, but i never get the response. 我在http服务器上收到了请求,但从未收到响应。 Have tested it in browsers, wget, curl, seems the problem is that it is not entering the
while(recv(sock, buf, 8192, 0) > 0)
loop, but the request is being made. 已经在浏览器中进行了测试,wget,curl,似乎问题在于它没有进入
while(recv(sock, buf, 8192, 0) > 0)
循环,但是正在发出请求。 It gives me Resource temporarily unavailable
basically. 它使我的
Resource temporarily unavailable
基本上Resource temporarily unavailable
。
OUTPUT : 输出:
AAAA
socket: Success
CCCC
socket: Illegal seek
socket: Operation now in progress
EEEE
socket: Illegal seek
44444
socket: Illegal seek
666666
7777777
socket: Illegal seek
8888888
socket: Illegal seek
tmpres=[133]
8.7 8.7 8.7
9999999
socket: Illegal seek
recv->[-1]
socket() failed: Resource temporarily unavailable
socket: Resource temporarily unavailable
socket: Resource temporarily unavailable
>>> CONTENT >>> []
11 11 11
12 12 12
socket: Resource temporarily unavailable
EDIT 编辑
puts(getcmd);
is : 是:
GET /script.php?v=qqqqq HTTP/1.0
Host: 1.2.3.4
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; rv:2.2) Gecko/20110201
(here is /r/n/r/n probably)
Any hint? 有什么提示吗?
Thank you! 谢谢!
i did a
fcntl(sock, F_SETFL);
我做了一个
fcntl(sock, F_SETFL);
after theif(select(sock + 1, NULL, &fdset, NULL, &tv) == 1) ...
part and i still get no content在
if(select(sock + 1, NULL, &fdset, NULL, &tv) == 1) ...
我仍然没有任何内容
You may not omit the third arg of the fcntl(sock, F_SETFL, …)
call; 您可能不会忽略
fcntl(sock, F_SETFL, …)
调用的第三个参数 ; to remove the O_NONBLOCK
flag, you can call fcntl(sock, F_SETFL, 0)
. 要删除
O_NONBLOCK
标志,可以调用fcntl(sock, F_SETFL, 0)
。
In addition, you may not omit the second connect
call after the non-blocking first connect
yielded Operation now in progress , so remove the commenting around the second call. 此外,在非阻塞的第一个
connect
产生“ Operation”(正在进行操作)之后,您可能不会省略第二个connect
呼叫,因此请删除第二个呼叫周围的注释。
Furthermore, the line 此外,线
printf("recv->[%d]\n",recv(sock, buf, 8192, 0));
already receives the first chunk of the web page content (or the entire content if small enough), but you discard what's in buf
and don't display what was received. 已经接收到网页内容的第一块(如果足够小,则接收全部内容),但是您将丢弃
buf
,而不显示接收到的内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.