【发布时间】:2021-10-30 04:21:32
【问题描述】:
我有一段 C 代码应该连接到 www.google.com 并发出 HTTP GET 请求,但是当我运行它时,它会在“正在连接..”上停留大约 30 秒,然后返回“连接失败”和退出返回值为 255。我做错了什么?
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define PORT 8000
struct hostent *hostinfo;
int main(void) {
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *hostname = "www.google.com";
char *request = "GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n";
hostinfo = gethostbyname(hostname);
char *ip = inet_ntoa(*(struct in_addr*)hostinfo->h_addr_list[0]);
char buffer[1024] = {0};
printf("Creating socket...\n");
if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0){
printf("\n Socket creation error \n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
printf("Checking address...\n");
if(inet_pton(AF_INET, ip, &serv_addr.sin_addr) <= 0){
printf("\n Invalid IP/Address not supported \n");
return -1;
}
printf("Connecting to host %s...\n", ip);
if(connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0){
printf("\n Connection Failed \n");
return -1;
}
send(sock, request, strlen(request), 0);
printf("Message sent\n");
valread = read(sock, buffer, 1024);
printf("%s\n", buffer);
return 0;
}
【问题讨论】:
-
@TedLyngmo - 就是那样的一天 :) 已删除
-
好像连接失败了。 Google 是否使用端口 8000?
-
可能没有直接关系,但
connect的第三个参数应该是sizeof struct sockaddr而不是sizeof struct sockaddr_in。 -
@WilliamPursell 这是错误的。
connect()期望传入的结构的 actual 大小。所以sizeof struct sockaddr_in是正确的值,因为serv_addr实际上是sockaddr_in而不是sockaddr(它们只是 恰好在大多数系统上大小相同)。如果serv_addr是 IPv6 的sockaddr_in6,则需要传入sizeof struct sockaddr_in6。如果您在使用sockaddr_in6时尝试传入sizeof struct sockaddr,connect()将失败并出现不同的错误。 -
附带说明:Google 现在完全使用 HTTPS,因此在端口 80 (
http:) 上向www.google.com发送未加密的 HTTP 请求实际上不会检索该页面,它会返回HTTP 重定向到端口 443 (https:) 上的www.google.com。此代码尚未设置为处理 HTTPS,因此它实际上无法从 Google 上的任何位置检索任何内容。