tags:

views:

32

answers:

1

Hi,

I am writing code for a webserver and am trying to send a html file called index.html over a TCP socket. How would I do this?

At the moment I am trying to read the contents of the file and then send them over the connection. However, the page is not being received correctly. I suspect that I am using the wrong function to read. But am not sure what else to do =s. Please help!

At the end of the code I'm closing and clearing out all the files and buffers.

while(!feof(sendFile)){

fgets(send_buffer, MAX_LEN, sendFile);

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

Here is the function I am trying to implement. This is just to return the http 404 error page:

} 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
}
A: 

Assuming you are sending the correct HTTP headers prior to sending the file contents (in particular, a Content-Length header), then you have to keep in mind that fgets() is designed for reading strings, but HTTP operates on binary data instead. You should be using fread() instead of fgets(). Also, when calling send(), you need to specify only the number of bytes that fgets/fread() actually return, do not send the entire buffer unless the entire buffer was actually filled in. Lastly, you need to take into account that send() can accept/transmit fewer bytes than what you request, so you may need to call send() multiple times for a single buffer.

Try this:

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 );
} 
Remy Lebeau - TeamB
I'm trying with fread but the compiler keeps saying "called object fread is not a function". I've included both the <stdio.h> plus <stdlib.h> libraries. Here is one of the functions I'm trying to implement. The headers are being sent fine. Except I'm not sure how to send the Content-Length header without reading the entire file - also not sure how to include it in the send().
BAkz
Okay I just got it working. I was using fread as a file descriptor to open files as well. Whoops!
BAkz
You can use the fseek() and ftell() functions to determine the file's size without reading the file contents. You have to send all HTTP headers, including Content-Length, before you can send the actual file contents. You have to send() the headers separately from your file send().
Remy Lebeau - TeamB
WOrks now =). Thanks!
BAkz