如何通过TCP套接字读取和发送html文件?

时间:2010-09-09 07:02:59

标签: sockets

我正在为网络服务器编写代码,我正在尝试通过TCP套接字发送一个名为index.html的html文件。我该怎么做?

目前我正在尝试读取文件的内容,然后通过连接发送它们。但是,页面未正确接收。我怀疑我使用了错误的功能来阅读。但我不知道还有什么可做的。请帮忙!

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

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 个答案:

答案 0 :(得分: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 );
}