0
我有一個小程序讓我通過TCP連接;並具有文本交換:URL名稱解析沒有按預期行事
#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
,地址解析,I型GET /
,我也得到該流的轉儲。
但是,如果我輸入$ ./client towel.blinkenlights.nl 23
;該程序退出。
$ echo $?
2
...告訴我resolve
沒有返回數據有效的connect_to
。我不明白爲什麼。
謝謝!我認爲幾乎所有需要修復的bug都與這樣的明顯錯誤有關;主要是因爲它們非常明顯。 – motoku