Link to home
Start Free TrialLog in
Avatar of bachra04
bachra04Flag for Canada

asked on

simple web server not working correctly

Hi experts,

I modified some code in order to create a simple webserver for my testing. The problem  is that the server accepts the connection correctly and send the response. But the client cannot read correctly from the socket once he gets the response.
Can you figure out what I'm doing wrong by looking at the code below?
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <netinet/in.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdarg.h>
#include <arpa/inet.h>
#include <unistd.h>

#define PORT 80
#define MLEN 1000
#define BUFSIZE 8192

int main(int argc, char *argv [])
{

        int listenfd, connfd;
        int number, message, numbytes;
        int h, i, j;
		socklen_t  alen; 
        int nread;
        struct sockaddr_in servaddr; 
        struct sockaddr_in cliaddr;
        FILE *in_file, *out_file, *fp;
        char buf[8192];



        listenfd = socket(AF_INET, SOCK_STREAM, 0);
        if (listenfd < 0)
                 fprintf(stderr,"listen error") ;

        memset(&servaddr, 0, sizeof(servaddr));
        servaddr.sin_family      = AF_INET;
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        servaddr.sin_port        = htons(PORT);

        if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
                fprintf(stderr,"bind error") ;

		listen(listenfd, 5);


        alen = sizeof(struct sockaddr);

		
		
        while ((connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &alen)) > 0)
        {
		

	        printf("accept one client from %s!\n", inet_ntoa(cliaddr.sin_addr));



			if (fork() == 0)
			{
					close(listenfd);
				printf("reading from socket");
				bzero(buf, BUFSIZE);
				numbytes = read (connfd, buf, BUFSIZE);
				if (numbytes < 0) printf("error reading from socket");
				sleep(1);

				bzero(buf, BUFSIZE);


		 		fp = fopen (argv [1], "r"); // open file stored in server
				if (fp == NULL) {
				        printf("\nfile NOT exist");
				}

				//Sending file
				while(!feof(fp)){

				        numbytes = fread(buf, sizeof(char), sizeof(buf), fp);
				        printf("fread %d bytes, ", numbytes);
				        numbytes = write(connfd, buf, numbytes);
				        printf("Sending %d bytes\n",numbytes);
				}

				fclose (fp);    
				sleep(5);
				close(connfd);
					exit(0);
        		}
			close(connfd);
	}
        	
        return 0;
}

Open in new window

Avatar of jkr
jkr
Flag of Germany image

A shot in the dark, but it seems you're not sending any HTTP headers. Try sending

"Content-type: text/plain\n\n"

Open in new window


before actually sending the file's contents.
BTW, see also http://en.wikipedia.org/wiki/HTTP_header

The simple header I posted above is the least you have to send with a web server's response (given that this response ist "text/plain").
Avatar of bachra04

ASKER

I'm reading the http contents from a file and I could see it in the wireshark. But it looks something is not done correctly on the socket side.
So, does that start with "Content-type: text/plain\n\n"? (Or the appropriate header?)
I have used the following code as well , I can see the response but my client is failing:
write(connfd, "HTTP/1.1 200 OK\n", 16);
        write(connfd, "Content-length: 46\n", 19);
        write(connfd, "Content-Type: text/html\n\n", 25);
        write(connfd, "<html><body><H1>Hello world</H1></body></html>",46);
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I added some debug info and it turns out my client is failing the response because of the missing \r\n in the header, every header has to end with \r\n instead of \n only. after replacing \n by \r\n it is now working fine.
I just have one extra question:
When I read from file using fread
The following :

HTTP/1.1 200 OK\r\n

is converted to :

HTTP/1.1 200 OK\\r\\n

is there a way to avoid that ?
If you were on Windows - yes. But you seem to be un UN*X, and that should not happen there. Are you sure the duplicate backslash isn't already there? Maybe you could check that with a hex editor.
That's weird,

It is under ubuntu. the only work around I 've found was to remove \r\n from the file.
Then when I saved it under gedit it gave me the option to save it with Line ending as windows and like that the problem
was solved.
Weird, indeed :-/