微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 C 中的套接字向 http/https 网站发送 GET 请求

如何解决如何使用 C 中的套接字向 http/https 网站发送 GET 请求

我想下载网页的内容。 当我向 example.com 发出 get 请求时,我可以建立连接。

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int main(void) {
    //Stream sockets and rcv()
    
    struct addrinfo hints,*res;
    int sockfd;
    
    char buf[2056];
    int byte_count;
    
    //get host info,make socket and connect it
    memset(&hints,sizeof hints);
    hints.ai_family=AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    getaddrinfo("example.com","80",&hints,&res);
    sockfd = socket(res->ai_family,res->ai_socktype,res->ai_protocol);
    printf("Connecting...\n");
    connect(sockfd,res->ai_addr,res->ai_addrlen);
    printf("Connected!\n");
    char *header = "GET /index.html HTTP/1.1\r\nHost: example.com\r\n\r\n";
    send(sockfd,header,strlen(header),0);
    printf("GET Sent...\n");
    //all right ! Now that we're connected,we can receive some data!
    byte_count = recv(sockfd,buf,sizeof(buf)-1,0); // <-- -1 to leave room for a null terminator
    buf[byte_count] = 0; // <-- add the null terminator
    printf("recv()'d %d bytes of data in buf\n",byte_count);
    printf("%s",buf);
    return 0;
}

但是如果代替 www.example.com 如果我使用 http://info.cern.ch/http://galileoandeinstein.physics.virginia.edu/lectures/newton.pdf(下载 pdf),我会遇到分段错误(端口号为 80 和 443)。

不起作用的代码

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int main(void) {
    //Stream sockets and rcv()
    
    struct addrinfo hints,sizeof hints);
    hints.ai_family=AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    getaddrinfo("http://galileoandeinstein.physics.virginia.edu/lectures/newton.pdf",res->ai_addrlen);
    printf("Connected!\n");
    char *header = "GET /index.html HTTP/1.1\r\nHost: http://galileoandeinstein.physics.virginia.edu/lectures/newton.pdf\r\n\r\n";
    send(sockfd,buf);
    return 0;
}

解决方法

getaddrinfo()Host:(在标头中)应该指定主机名(不是完整的 URI)。

在您的示例中,这是 galileoandeinstein.physics.virginia.edu

因为您没有检查 getaddrinfo() 的结果,所以您没有检测到 res 指针在失败的情况下没有正确初始化。 然后,使用指向结构的成员会产生分段违规。

请求头应该类似于

"GET /lectures/newton.pdf HTTP/1.1\r\n"
"Host: galileoandeinstein.physics.virginia.edu\r\n"
"Connection: close\r\n"
"\r\n"

Connection: close 不是必需的,但可以简化您的简单实验。

为了试验 HTTPS,this example 可能是一个很好的起点。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。