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,而不是\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 ...

所以这是要寻找的一件事。消息可能永远不会到达您的服务器。

但是,不管怎样,您应该为自己获取一份WireShark(免费)或其他网络嗅探器程序的副本,这样您就可以准确地看到幕后发生的事情。

这将极大地帮助调试这些类型的问题。

于 2011-05-29T05:07:16.987 回答