[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

simple web server not working correctly

Posted on 2014-08-18
11
Medium Priority
?
231 Views
Last Modified: 2014-08-19
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

0
Comment
Question by:bachra04
  • 6
  • 5
11 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 40269250
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.
0
 
LVL 86

Expert Comment

by:jkr
ID: 40269253
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").
0
 
LVL 2

Author Comment

by:bachra04
ID: 40269264
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.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 86

Expert Comment

by:jkr
ID: 40269277
So, does that start with "Content-type: text/plain\n\n"? (Or the appropriate header?)
0
 
LVL 2

Author Comment

by:bachra04
ID: 40269346
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);
0
 
LVL 86

Accepted Solution

by:
jkr earned 2000 total points
ID: 40269354
What error code are you gettng (and, please use 'strlen()' for determning the length of each header line - or, even beter, a 'std::string')
0
 
LVL 2

Author Closing Comment

by:bachra04
ID: 40269417
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.
0
 
LVL 2

Author Comment

by:bachra04
ID: 40270707
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 ?
0
 
LVL 86

Expert Comment

by:jkr
ID: 40270795
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.
0
 
LVL 2

Author Comment

by:bachra04
ID: 40271062
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.
0
 
LVL 86

Expert Comment

by:jkr
ID: 40271143
Weird, indeed :-/
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
Suggested Courses

872 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question