socket 请求接收完整的一个http响应(设置recv 接收超时选项SO_RCVTIMEO)
2013-11-08 14:35
901 查看
在前面的系列网络编程文章中,我们都是使用socket 自己实现客户端和服务器端来互相发数据测试,现在尝试使用socket 客户端发
送http 请求给某个网站,然后接收网站的响应数据。http 协议参考 这里。
代码如下:
C++ Code
输出如下:
.............................省略................................
从上面的输出可以看到有完整的<html> </html> ,即已经完整接收,但有一点不解的是为什么最后会接收到一个0?程序中
struct timeval timeout = {3,0};
setsockopt(socket_desc, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval));
设置超时时间为3s,现在recv 为阻塞接收,如果超时时间内接收缓冲区没有一点数据,则返回-1 且errno = EWOULDBLOCK 。
退出循环,程序结束。
在这里顺便提一下,recv的第四个参数如果设置为MSG_WAITALL,在阻塞模式下不等到指定数目的数据是不会返回的,除非超时时间到。但在这里我们并不知道对方会发来具体多少数据,所以不能使用这种方法来读取数据,否则可能出现一直阻塞的情况。
送http 请求给某个网站,然后接收网站的响应数据。http 协议参考 这里。
代码如下:
C++ Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | #include<stdio.h> #include<stdlib.h> #include<string.h> //strlen #include<sys/socket.h> #include<arpa/inet.h> //inet_addr #include<netdb.h> #include<errno.h> int main(int argc , char *argv[]) { int socket_desc; struct sockaddr_in server; char *message; //Create socket socket_desc = socket(AF_INET , SOCK_STREAM , 0); if (socket_desc == -1) { printf("Could not create socket"); } char ip[20] = {0}; char *hostname = "www.google.com.hk"; struct hostent *hp; if ((hp = gethostbyname(hostname)) == NULL) return 1; // #define h_addr h_addr_list[0] strcpy(ip, inet_ntoa(*(struct in_addr *)hp->h_addr_list[0])); server.sin_addr.s_addr = inet_addr(ip); server.sin_family = AF_INET; server.sin_port = htons( 80 ); //Connect to remote server if (connect(socket_desc , (struct sockaddr *)&server , sizeof(server)) < 0) { puts("connect error"); return 1; } puts("Connected\n"); //Send some data message = "GET /?st=1 HTTP/1.1\r\nHost: www.google.com.hk\r\n\r\n"; if( send(socket_desc , message , strlen(message) , 0) < 0) { puts("Send failed"); return 1; } puts("Data Send\n"); struct timeval timeout = {3, 0}; setsockopt(socket_desc, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval)); //Receive a reply from the server //loop int size_recv , total_size = 0; char chunk[512]; while(1) { memset(chunk , 0 , 512); //clear the variable if((size_recv = recv(socket_desc , chunk , 512 , 0) ) == -1) { if (errno == EWOULDBLOCK || errno == EAGAIN) { printf("recv timeout ...\n"); break; } else if (errno == EINTR) { printf("interrupt by signal...\n"); continue; } else if (errno == ENOENT) { printf("recv RST segement...\n"); break; } else { printf("unknown error!\n"); exit(1); } } else if (size_recv == 0) { printf("peer closed ...\n"); break; } else { total_size += size_recv; printf("%s" , chunk); } } printf("Reply received, total_size = %d bytes\n", total_size); return 0; } |
.............................省略................................
从上面的输出可以看到有完整的<html> </html> ,即已经完整接收,但有一点不解的是为什么最后会接收到一个0?程序中
struct timeval timeout = {3,0};
setsockopt(socket_desc, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval));
设置超时时间为3s,现在recv 为阻塞接收,如果超时时间内接收缓冲区没有一点数据,则返回-1 且errno = EWOULDBLOCK 。
退出循环,程序结束。
在这里顺便提一下,recv的第四个参数如果设置为MSG_WAITALL,在阻塞模式下不等到指定数目的数据是不会返回的,除非超时时间到。但在这里我们并不知道对方会发来具体多少数据,所以不能使用这种方法来读取数据,否则可能出现一直阻塞的情况。
相关文章推荐
- socket 请求接收完整的一个http响应(设置recv 接收超时选项SO_RCVTIMEO)
- socket 请求接收完整的一个http响应(设置recv 接收超时选项SO_RCVTIMEO)
- socket 请求接收完整的一个http响应(设置recv 接收超时选项SO_RCVTIMEO)
- http请求设置setConnectTimeout()方法超时无响应
- 怎么查看真实项目的http 请求的请求报文和响应报文,即request和response?只有这样,才能完全彻底明白一个http 请求整个过程,发送和接收的是什么东西。
- Python中使用socket发送HTTP请求数据接收不完整问题解决方法
- Python中使用socket发送HTTP请求数据接收不完整问题解决方法
- Windows 和 Linux下使用socket下载网页页面内容(可设置接收/发送超时)的代码(用socket解释http,不错)
- 一个HTTP连接是包含两部分的,请求报文和响应报文这俩组合起来才是一次完整的HTTP请求,并不会单独显示请求报文或者响应报文
- socket为send和recv设置 4000 超时时间
- HTTP的通信的 发送请求、接收响应 包含哪些内容?OC中是怎样实现的?
- http一个完整的请求?
- 为ServerXMLHTTP对象的HTTP请求设置超时时间
- j2ee的web项目,在浏览器中发起一个该项目中html页面的绝对地址,也是发起的一个http url请求,请求的响应报文的结果就是该html页面的所有html代码
- 接收对 http://192.168.1.18:8001/ObtainData/Service 的 HTTP 响应时发生错误。这可能是由于服务终结点绑定未使用 HTTP 协议造成的。这还可能是由于服务器中止了 HTTP 请求上下文(可能由于服务关闭)所致。
- socket的send、recv阻塞设置阻塞超时时间
- http一个完整的请求?
- 利用volley进行http设置请求头、超时及请求参数设置(post)
- 关于设置Http请求超时的办法
- C#中设置Socket连接请求的超时