2010-09-09 109 views
2

我正在为web服务器编写代码,并试图通过TCP套接字发送名为index.html的html文件。我将如何做到这一点?如何通过TCP套接字读取并发送html文件?

目前我正在尝试读取文件的内容,然后通过连接发送它们。但是,页面未被正确接收。我怀疑我正在使用错误的函数来阅读。但我不确定还有什么要做的= s。请帮忙!

在代码结束时,我正在关闭并清除所有文件和缓冲区。

while(!feof(sendFile)){ 

fgets(send_buffer, MAX_LEN, sendFile); 

send(new_fd,send_buffer,sizeof(send_buffer),0); 
} 

这是我试图实现的功能。这只是返回HTTP 404错误页面:前

} else { 
     len = strlen("HTTP/1.1 404 Not Found\n"); 
     send(new_fd, "HTTP/1.1 404 Not Found\n", len, 0); 
     send(new_fd,"Connection: Keep Alive\n",strlen("Connection: Keep Alive\n"),0); 
     send(new_fd,"Content-Type: html\n",strlen("Content-Type: html\n"),0); 
     //read and send the contents of the 404.html file 
     //open file 
     if((sendFile = fopen("404.html","r"))<0){ 
      printf("FILE DID NOT OPEN!\n"); 
      exit(1); 
     } 
     //obtain file size 
     fseek (sendFile , 0 , SEEK_END); 
     Fsize = ftell (sendFile); 
     rewind (sendFile); 

/*   // allocate memory to contain the whole file: 
     send_buffer = (char*) malloc (sizeof(char)*Fsize); 
     if(send_buffer == NULL){ 
      printf("Memory error"); 
      exit (1); 
     } 

     // copy the file into the buffer: 
     result = fread (send_buffer,1,Fsize,sendFile); 
     if(result != Fsize) { 
      printf("Reading error"); 
      exit (1); 
     } 
*/ 
     send(new_fd,"Content-Length: ",strlen("Content-Length: "),0); 
     send(new_fd,int(Fsize),4,0); //this line is causing errors!!!! 
     send(new_fd,"\n",strlen("\n"),0); 
     while(!feof(sendFile)){ 
      bzero(send_buffer,MAX_MSG); 
      fgets(send_buffer, sizeof(send_buffer), sendFile); 
      //result = send(new_fd,send_buffer,strlen(send_buffer),0); 
       if(send(new_fd,send_buffer,sizeof(send_buffer),0)!=sizeof(send_buffer)){ 
       printf("Sending 404.html Failed\n"); 
       break; 
      } 
     } 
     fclose(sendFile); 
     printf("Sent file\n"); 
    } 

} else if(strcmp(request_page, POST)==0){ 
    // THIS IS WHERE YOU CAN TACKLE POST MESSAGES 
} 

回答

1

假设您发送正确的HTTP标头(,一Content-Length头特别)发送该文件的内容,那么你要记住,FGETS ()专为读取字符串而设计,但是HTTP使用二进制数据。你应该使用fread()而不是fgets()。另外,在调用send()时,只需指定fgets/fread()实际返回的字节数,除非实际填充整个缓冲区,否则不要发送整个缓冲区。最后,您需要考虑send()可以接受/传输比你请求的字节更少的字节,所以你可能需要多次调用send()来获得单个缓冲区。

试试这个:

unsigned char send_buffer[MAX_LEN]; 

while(!feof(sendFile)) 
{ 
    int numread = fread(send_buffer, sizeof(unsigned char), MAX_LEN, sendFile); 
    if(numread < 1) break; // EOF or error 

    unsigned char *send_buffer_ptr = send_buffer; 
    do 
    { 
     int numsent = send(new_fd, send_buffer_ptr, numread, 0); 
     if(numsent < 1) // 0 if disconnected, otherwise error 
     { 
      if(numsent < 0) 
      { 
       if(WSAGetLastError() == WSAEWOULDBLOCK) 
       { 
        fd_set wfd; 
        FD_ZERO(&wfd); 
        FD_SET(new_fd, &wfd); 

        timeval tm; 
        tm.tv_sec = 10; 
        tm.tv_usec = 0; 

        if(select(0, NULL, &wfd, NULL, &tm) > 0) 
         continue; 
       } 
      } 

      break; // timeout or error 
     } 

     send_buffer_ptr += numsent; 
     numread -= numsent; 
    } 
    while(numread > 0); 
} 
+0

我用fread努力,但编译器口口声声说“称为对象的fread不是一个函数”。我已经包含了加上库。这是我试图实现的功能之一。头文件发送正常。除了我不确定如何在不读取整个文件的情况下发送Content-Length头,也不知道如何将其包含在send()中。 – BAkz 2010-09-10 02:29:51

+0

好吧,我刚刚得到它的工作。我使用fread作为文件描述符来打开文件。哎呦! – BAkz 2010-09-10 03:40:29

+0

您可以使用fseek()和ftell()函数来确定文件的大小,而无需读取文件内容。在发送实际文件内容之前,您必须发送所有HTTP标头,包括Content-Length。你必须从文件send()中分别发送()头文件。 – 2010-09-10 20:49:36