我正在尝试在C中构建代理服务器。我的问题如下,
我有一个函数fetch_response(),它连接到example.com并使用HTTP GET请求查询服务器。
int fetch_response() {
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[4096];
char *host = "example.com";
portno = 80;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(host);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) error("ERROR connecting");
const char * request = "GET / HTTP/1.0\r\nHost: example.com\r\nConnection: close\r\n\r\n";
n = write(sockfd,request,strlen(request));
if (n < 0) error("ERROR writing to socket");
bzero(buffer,4096);
n = read(sockfd,buffer,4095);
if (n < 0) error("ERROR reading from socket");
printf("%d\n", (int)strlen(buffer));
printf("%s\n",buffer);
close(sockfd);
return 0;
}
测试时运行正常,例如
int main() {
fetch_response();
return 0;
}
然而,在我的代理服务器中,我正在尝试处理多个客户端请求, 所以我的main()函数就像,
while(1) {
new_socket = accept(params);
if(new_socket < 0) error("Error on Connect");
pid = fork();
if(pid < 0) error("Error on fork");
if(pid == 0) {
fetch_response();
exit(0);
}
else close(new_socket);
}
在这种情况下,我遇到了一个问题。无论我的缓冲区大小是什么,我只收到所请求页面的前1328个字节。我用不同的域测试了它,结果是一样的。例如,在example.com的情况下,预期结果是,
<html>
<head></head>
<body><h1> Example Domain </h1>
< Some remaining body here >
</body>
</html>
但我得到了
<html>
<head></head>
<body><h1> Example Domain </h1>
我无法理解为什么会这样。请帮忙。
谢谢!
PS:这不是代理服务器的实际代码。为了进行调试,我对所有内容进行了评论并测试了上面的代码。
答案 0 :(得分:1)
你需要把你的阅读代码放在一个循环中,如下所示:
while (1) {
bzero(buffer,4096);
n = recv(sockfd,buffer,4095, 0);
if (n < 0) {
error("ERROR reading from socket");
break;
}
if (n == 0) {
// far end has closed socket
break;
}
// printf("%d\n", (int)strlen(buffer));
printf("%d\n", n);
printf("%s\n",buffer);
}
这将继续从套接字读取,直到远端关闭它。对于每次调用recv
,它将返回缓冲区中的字节数。当它返回0
时,远端已关闭套接字,并且不再需要读取。