gpt4 book ai didi

c - URL 名称解析未按预期运行

转载 作者:行者123 更新时间:2023-11-30 15:12:10 25 4
gpt4 key购买 nike

我有一个小程序可以让我通过 TCP 连接;并进行文本交换:

#include <arpa/inet.h>
#include <error.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>

#define BUFLEN 1024

int connect_to(char *host, int port) {
int sd;
struct sockaddr_in addr;
fd_set sfds;
struct timeval tv;

sd = socket(AF_INET, SOCK_STREAM, 0);
if (sd == -1) return sd;
if (fcntl(sd, F_SETFL, O_NONBLOCK) == -1) return -2;
memset(&addr, 0, sizeof (addr));
addr.sin_family = AF_INET;
if (inet_pton(AF_INET, host, &addr.sin_addr) != 1)
return -3;
addr.sin_port = htons(port);
connect(sd, (struct sockaddr *) &addr, sizeof (addr));
FD_ZERO(&sfds);
FD_SET(sd, &sfds);
tv.tv_sec = 4;
tv.tv_usec = 0;
if (select(sd + 1, NULL, &sfds, NULL, &tv)) return sd;
return -4;
}

int resolve(char *host) {
struct addrinfo hints, *servinfo;
struct in_addr addr;
char *addr_tmp;
int rv;

memset(&hints, 0, sizeof hints);
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = AF_INET;
rv = getaddrinfo(host, NULL, &hints, &servinfo);
if (rv) return -1;
addr.s_addr = ((struct sockaddr_in*)servinfo->ai_addr)->sin_addr.s_addr;
addr_tmp = inet_ntoa(addr);
memcpy(host, addr_tmp, strlen(addr_tmp));
freeaddrinfo(servinfo);
return 0;
}

sig_atomic_t run = 1;

void sig_handler(int sig) { run = 0; }


int transfer(int fd_in, char *buf, int buf_len, int fd_out) {
int len = read(fd_in, buf, buf_len);
return len > -1? write(fd_out, buf, len) - len: -1;
}

int main(int argc, char **argv) {
int sd, rv;
fd_set fds;
struct timeval tv;
char buffer[BUFLEN];
char host[256], *port;

memcpy(host, argv[1], strlen(argv[1]) + 1);
port = argv[2];
sd = connect_to(host, atoi(port));
if (sd < 0) {
if (resolve(host) < 0) return 1;
else sd = connect_to(host, atoi(port));
if (sd < 0) return 2;
}

write(STDOUT_FILENO, "connected\n", 11);

signal(SIGINT, sig_handler);

FD_ZERO(&fds);
tv.tv_sec = 0;
tv.tv_usec = 100000;
while (run) {
FD_SET(sd, &fds);
FD_SET(STDIN_FILENO, &fds);
(void)select(sd + 1, &fds, NULL, NULL, &tv);
if (FD_ISSET(STDIN_FILENO, &fds)) rv = transfer(STDIN_FILENO, buffer, BUFLEN, sd);
if (FD_ISSET(sd, &fds)) rv = transfer(sd, buffer, BUFLEN, STDOUT_FILENO);
if (rv < 0) return 3;
}
close(sd);

return 0;
}

如果我输入 $ ./client google.com 80,地址就会解析,我输入 GET/,就会得到该流的转储。

但是,如果我输入 $ ./client towel.blinkenlights.nl 23;程序退出。

$ echo $?
2

...告诉我 resolve 未返回对 connect_to 有效的数据。我不明白为什么。

最佳答案

问题出在这里:

memcpy(host, addr_tmp, strlen(addr_tmp));

您不能以空值终止字符串。尝试使用

strcpy(host, addr_tmp);

否则,原始主机名的其余部分将保留并使 IP 地址无效(1.2.3.4nkenlights.nl 或类似地址)。 google.com 足够短,可以完全覆盖,碰巧 IP 地址在那里以 null 结尾。

关于c - URL 名称解析未按预期运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35212806/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com