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;
  }
}

そして、handlerequset関数は次のとおりです。

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));
}

ページが単純なグローバル変数である場合:

char * page = "HTTP / 1.0 200 OK \ r \ nContent-Type:text / html \ r \ n \ r \n<h1>こんにちは</h1>\ r \ n";

何が起こるかというと、そのブラウザは待機していて(データを受信して​​いるようで、タブの円が回転しているようです)、何も表示しません(FirefoxとChromiumを試しました)。(accept()を使用して)メインプロセスを強制終了した後でのみ、ページが表示されます。

どこが問題になるのかわかりませんが、正しくやっていると思います。新しいプロセスの場合は、応答を送信し、acceptによって返された記述子を閉じて子を閉じます。

4

1 に答える 1

0

ブラウザはまだデータを待っているため、「ハング」しています。これ以上データがなくなることを知る方法は 2 つあります。コンテンツの長さを示すヘッダー ( content-length) を介して、またはサーバーが送信を終了したことを示すソケットを閉じることによって。

コードには2つの主な問題があります.メインプロセスとフォークされたプロセスの両方でソケットを閉じていませんが、戻ってくるだけです.メインプロセスでこれを実行していると思われます.一般に、分岐した子で exit() を呼び出すことをお勧めします。そうしないと、それらは実行され続け、厄介で見つけにくいバグにつながる可能性があります。while ループで閉じないnewFdと、最終的にソケット記述子が不足し、サーバーは新しい要求を受け入れることができなくなります。

于 2012-11-26T06:26:15.580 に答える