1

私が抱えている主な問題はコード自体にあるようには見えませんが、念のためコードを投稿しました。まず、サーバーを実行し、別のターミナルで「telnet localhost 46745」を使用すると、localhost への接続が成功します。次に、「GET /hello.html HTTP/1.1」と入力します。hello.html ファイルは、サーバーが実行されているディレクトリにあります。とにかく、GET メソッドは、hello.html ファイルの両方のコード行を返します。わかりました、それはうまくいくようです。問題は、Firefox にアクセスし、ブラウザで「http://localhost:46745/hello.html 」と入力したときに発生します。"、エラーメッセージは表示されませんが、ブラウザが回転して「ローカルホストを待っています...」と表示されます。この問題を引き起こしている可能性のある問題 (コードまたはブラウザ内) は何ですか。何時間も無駄に、はい、これは宿題です. ありがとう.

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>   /* Internet domain header */
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <signal.h>

#define SA struct sockaddr
#define SERVER_PORT  46745
#define MAX_LINE     256
#define BUFFER_SIZE 10000
#define MAX_PENDING  5

int  soc ;    /* socket for server */

void signal_catcher( int the_sig ) {
  printf("terminating the server socket number %d\n",soc) ;
  close( soc ) ;
  exit(0) ;
}

int main() {
  struct sockaddr_in serv_addr, clnt_addr;
  char buf[BUFFER_SIZE];
  int len, new_s, bytes_read;
  char response[MAX_LINE];
  char fileExt[MAX_LINE];
  char* token;

  /* remove socket for server when terminating */
  if( signal(SIGINT, signal_catcher ) == SIG_ERR ){
    perror("SIGINT") ;
    exit(13) ;
  }

  if( signal(SIGQUIT, signal_catcher ) == SIG_ERR ){
    perror("SIGQUIT") ;
    exit(14) ;
  }

  /* set up listening socket soc, passive open */
  if ( (soc = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
    perror("server: socket"); 
    exit(1);
  }

  /* build address data structure */
  serv_addr.sin_family = AF_INET ;
  serv_addr.sin_addr.s_addr = htonl(INADDR_ANY) ;
  serv_addr.sin_port = htons(SERVER_PORT) ;

  if (bind(soc, (SA *)  &serv_addr, sizeof(serv_addr)) < 0) {
    perror("server: bind");
    close(soc);
    exit(1);
  }

  if(listen(soc, MAX_PENDING) < 0) {
    perror("server: listen");
    close(soc);
    exit(1);
  }

  printf("Socket number for server = %d\n",soc);

  /* accept connection, then receive and print text */
  while ( 1 ) {
    len = sizeof(clnt_addr) ;
    if ( (new_s = accept(soc, (SA *)  &clnt_addr , &len) ) < 0 ) {
      perror("server:  accept"); 
      close(soc);
      exit(1);
     }

  printf("\nConnect from host %s, port %hd\n",inet_ntoa(clnt_addr.sin_addr), ntohs(clnt_addr.sin_port) );

  memset(buf,0x0,BUFFER_SIZE);    //  init line 

  while( len = recv( new_s, buf, sizeof( buf ), 0 ) ) {
    if (strstr(buf,"GET")) {
      token=strtok(buf," ");
      token=strtok(NULL," ");
      sprintf(fileExt,".%s",token);
    FILE *fp;
    fp=fopen(fileExt, "r");
    if (fp!=NULL) {
              send(new_s, "HTTP/1.1 200 OK\r\n\r\n", 23, 0);
              while(bytes_read=fread(response, 1, sizeof(response), fp)) {
                int length = strlen(response)-1;
                if(response[length] == '\n') {
                  response[length] = 0;
                }
                send(new_s, response, bytes_read, 0 );
                fclose(fp);
              }
        } else {
                send(new_s, "HTTP/1.1 404 Not Found\r\n\r\n", 30, 0);
              }
     }// end if strstr
 else {
  send(new_s, "HTTP/1.1 400 Invalid Request\r\n\r\n", 36, 0);
 }
  }// end while from recv

  }// end while(1)
  close ( new_s );
return(0);
}
4

3 に答える 3

4

クライアントへの対応に小さな間違いがいくつかあります。まず、行\n\nの前に出力していますHTTP/1.1 XXX Some StatusHTTP/1.1最初にする必要があります。その前はありません\n\n。次に、\nその後に s を出力しています。HTTP 仕様では\r\n、 , notを使用する必要があると指定されています\n(ただし、Firefox はこれを処理できるはずです)。最後に、ステータス コード 400 および 404 の場合、コンテンツは返されません。たとえそれが空であっても、おそらくそうするべきです。

于 2011-05-29T05:10:37.043 に答える
3

行末記号は技術的には CRLF ("\r\n") であり、LF ("\n") ではありません。

これはあなたの問題ではないかもしれませんが、確かに問題です。

于 2011-05-29T05:09:50.430 に答える
0

サーバーが次のようなメッセージを出力しているかどうかはわかりません。

Connect from host ...

それは探すべきことの1つです。メッセージがサーバーに届かない可能性があります。

ただし、それにもかかわらず、WireShark (無料) または別のネットワーク スニファ プログラムのコピーを入手して、内部で何が起こっているかを正確に確認する必要があります。

これは、この種の問題のデバッグに大いに役立ちます。

于 2011-05-29T05:07:16.987 に答える