3

您好我正在尝试编写一个非常简单的网络服务器。它将对任何请求响应相同的简单网页。这是代码片段:

while(1) {

  if ((newFd = accept(s, (struct sockaddr *) &clientAddr, &sockAddrSize)) == ERROR) {
      printf("error accept\n");
      close(s);
      return;
   }

  pid = fork();

  if(pid == 0) {
      handle_request(newFd);
      close(newFd);
      return;
  }
}

句柄请求函数是:

void handle_request(int newFd) {

  int readBytes;
  int sendBytes;
  readBytes = recv(newFd, buffer, BUFFSIZE, 0);

  sendBytes = send(newFd, page, strlen(page), 0);
  printf("I have send %d B out of %d B\n", sendBytes, strlen(page));
}

其中 page 是简单的全局变量:

char *page = "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>Hello</h1>\r\n";

发生的情况是,该浏览器正在等待(似乎正在接收数据,选项卡中的圆圈正在旋转)并且什么都不显示(尝试了 Firefox 和 Chromium)。只有在我杀死主进程(使用accept())之后,它才会显示页面。

我不知道哪里有问题,我想我做得对。对于新进程,我发送响应并关闭接受返回的描述符并关闭子进程。

4

1 回答 1

0

浏览器“挂起”,因为它仍在等待数据。它有两种方法可以知道不会有更多的数据。通过标明内容长度的标头 ( content-length) 或通过服务器关闭表明服务器已完成发送的套接字。

您的代码中有两个主要问题,您没有在主进程和分叉进程中关闭套接字,但您只是返回,我怀疑您在主进程中运行它,这无关紧要,但在一般来说,在分叉的孩子中调用 exit() 是一种很好的做法。如果您不这样做,它们将继续运行,并可能导致一些令人讨厌且难以发现的错误。如果您不在newFdwhile 循环中关闭,您最终将用完套接字描述符,并且您的服务器将无法接受新请求。

于 2012-11-26T06:26:15.580 回答