【发布时间】:2017-03-31 11:34:24
【问题描述】:
我正在尝试用 C 编写一个 REST 客户端。目前它是独立的,但稍后我计划将其移植到我们的代码库中。
我正在使用 gcc 在 centos 6.5 上对此进行测试。
我从https://gist.github.com/nolim1t/126991 的代码开始作为参考。这是由几个成员在quora中提出的。
我调整了上面的代码以满足我的需要。当我尝试这个时,我无法从其他服务器获得有效的响应。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
int socket_connect(char *host, in_port_t port){
struct hostent *hp;
struct sockaddr_in addr;
int on = 1, sock;
if((hp = gethostbyname(host)) == NULL){
herror("gethostbyname");
exit(1);
}
bcopy(hp->h_addr, &addr.sin_addr, hp->h_length);
addr.sin_port = htons(port);
addr.sin_family = AF_INET;
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&on, sizeof(int));
if(sock == -1){
perror("setsockopt");
exit(1);
}
if(connect(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) == -1){
perror("connect");
exit(1);
}
return sock;
}
#define BUFFER_SIZE 1024
int main(int argc, char *argv[]){
int fd;
int cx;
char inputBuffer[BUFFER_SIZE];
char buffer[BUFFER_SIZE];
if(argc < 4){
fprintf(stderr, "Usage: %s <hostname> <port> <other-args>\n", argv[0]);
exit(1);
}
fd = socket_connect(argv[1], atoi(argv[2]));
if(fd)
{
printf("socket success\n");
}
cx = snprintf(inputBuffer, BUFFER_SIZE, "GET %s\r\n", argv[3]);
// snprintf(inputBuffer, argv[3], strlen(argv[3]));
write(fd, inputBuffer, cx); // write(fd, char[]*, len);
bzero(buffer, BUFFER_SIZE);
printf("reading response\n");
while(read(fd, buffer, BUFFER_SIZE - 1) != 0){
fprintf(stderr, "%s", buffer);
bzero(buffer, BUFFER_SIZE);
}
shutdown(fd, SHUT_RDWR);
close(fd);
return 0;
}
这是我正在访问的其他类似 url: http://maps.googleapis.com/maps/api/geocode/json?address=chicago
当我通过浏览器访问它时,我可以访问 json 数据/响应。 但是,当我使用 C 程序时,我得到以下输出。
#./rest maps.googleapis.com 80 /maps/api/geocode/json?address=chicago
socket success
reading response
它会无限期地停留在那里。
当我通过 C 程序和浏览器访问时,我正在附加数据包捕获和 tcp 流。
编辑:
感谢您的回复。我原来的程序有效。调试了这个,发现公司防火墙阻止了数据包,因此我没有得到响应。
对于@eyllanesc 发布的答案 - 此代码部分有效。由于某种未知原因,来自服务器的 FIN 数据包没有立即到来。从发送第一个数据包开始总是需要 4 分钟。 所以程序在终止之前保持挂起 4 分钟。不过感谢您的努力。
【问题讨论】:
-
不可重复,
./your_prog maps.googleapis.com 80 "/maps/api/geocode/json?address=chicago"吐出正确结果 -
谢谢。是的,这是一个环境问题。
-
您的
read()调用将无限期地等待BUFFER_SIZE - 1字节。但是没有那么多字节要读取。所以你的read()无限期地等待,直到服务器关闭连接。