使用C套接字编程获取网页

时间:2015-10-09 07:55:02

标签: c proxy network-programming

我正在尝试在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:这不是代理服务器的实际代码。为了进行调试,我对所有内容进行了评论并测试了上面的代码。

1 个答案:

答案 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时,远端已关闭套接字,并且不再需要读取。