I am trying to read the contents from the specified file into a char array and then send that to the client. The problem i get is that getline() wont take a char array as a parameter and strcat() wont take a string as a parameter so I dont know what to do. Are there other functions i could use? I dont know of any so any help will be VERY appreciated.

Lines in question are 78 and 80

#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <cstring>
#include <iostream>
#include <string>
using namespace std;

int parseARGS(char **args, char *line){
int tmp=0;
args[tmp] = strtok( line, " /" );
while ( (args[++tmp] = strtok(NULL, " ,/" ) ) != NULL );
return tmp - 1;
}

void error(char *msg)
{
    perror(msg);
    exit(1);
}

int main(int argc, char *argv[])
{
     int sockfd, newsockfd, portNum, clilen;
     int nbytes=0;
     char *line;
     char *header[4096];
     char *filename;	
     char buffer[1024];
     char filebuffer[4096];
     char strfinal[4096];		 
     struct sockaddr_in serv_addr, cli_addr;
     int n, percent, count1, count2;
     int received = 0;


     if (argc < 2) {
         fprintf(stderr,"ERROR, no port provided\n");
         exit(1);
     }
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     if (sockfd < 0) 
        error("ERROR opening socket");
     portNum = atoi(argv[1]);
     serv_addr.sin_family = AF_INET;
     serv_addr.sin_addr.s_addr = INADDR_ANY;
     serv_addr.sin_port = htons(portNum);
     if (bind(sockfd, (struct sockaddr *) &serv_addr,
              sizeof(serv_addr)) < 0) 
              error("ERROR on binding");
     listen(sockfd,5);
     clilen = sizeof(cli_addr);
	while(1){
     newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t*)&clilen);
     if (newsockfd < 0) 
          error("ERROR on accept");
	n = read(newsockfd,buffer,1023);
       parseARGS(header, buffer);
       filename = header[1];
	printf("Here is the message: %s\n",filename);
	if (n < 0) error("ERROR reading from socket");
       ifstream myfile (filename);
	strcat(strfinal, "HTTP/1.0 200 OK \r\n\r\n");
	if (myfile.is_open()) //if the file is open
	{
		while (! myfile.eof() ) //while the end of file is NOT reached
		{
			getline (myfile,line);
			cout << line << endl;
			strcat(strfinal, line);
		}
	}  
       send(newsockfd, strfinal, sizeof(strfinal), 0);
       if(nbytes < 0) {
		perror("sendto");	
		exit(1);
	}
    close(newsockfd);
            
}
	
     return 0; 
}

Recommended Answers

All 7 Replies

in line 80 try

strcpy (strfinal, line.c_str());

instead of

getline (myfile,line);

in line 80 try

strcpy (strfinal, line.c_str());

instead of

getline (myfile,line);

I changed the code to

while (! myfile.eof() ) //while the end of file is NOT reached
		{
			getline (myfile,line);
			strcat (strfinal, line.c_str());
		}

and with a one line txt file it works, but it only copied a small portion of a larger .cpp file. Also, when I used 'diff' in unix to compare the output from the simple txt file it said "Binary files test.txt and test.txt.1 differ". Why and how can I get it to be the exact same?

line 36:
should to be: std::string line;

line 80:
strcat(strfinal, line.c_str() );

instread of:

while (! myfile.eof() ) //while the end of file is NOT reached
		{
			getline (myfile,line);
			cout << line << endl;
			strcat(strfinal, line);
		}

better:

while (getline (myfile,line)) //while the end of file is NOT reached
		{
			cout << line << endl;
			strcat(strfinal, line);
		}

and to make it more smooth

instread of:

strcat(strfinal, "HTTP/1.0 200 OK \r\n\r\n");
	if (myfile.is_open()) //if the file is open
	{
		while (! myfile.eof() ) //while the end of file is NOT reached
		{
			getline (myfile,line);
			cout << line << endl;
			strcat(strfinal, line);
		}
	}  
       send(newsockfd, strfinal, sizeof(strfinal), 0);

better:

#include <stringstream>
std::sstream ss; 

    ss << "HTTP/1.0 200 OK \r\n\r\n";
    
	if (myfile.is_open()) //if the file is open
	{
		while (getline (myfile,line) ) //while the end of file is NOT reached
		{
			cout << line << endl;
			ss << line;
		}
	}  
    
    send(newsockfd, ss.str().s_str(), ss.str().size(), 0);

@programmersbook

I get a compiler error when I use that code

WebServer.cpp:89: no matching function for call to `std::basic_string<char,
   std::char_traits<char>, std::allocator<char> >::s_str()'

how I put it in:

#include <sstream>
stringstream ss;
if (myfile.is_open()) //if the file is open
	{	
		ss << "HTTP/1.0 200 OK \r\n\r\n";
		while (getline(myfile, line))
		{			
			ss << line;
		}
		nbytes=send(newsockfd, ss.str().s_str(), ss.str().size(), 0);
              if(nbytes < 0) {
		    perror("send error");	
		    exit(1);
		}

**RESOLVED**
Here is my finished code of a web server that receives a file request from a browser and returns the specified file (the text of that file).

#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <cstring>
#include <iostream>
#include <string>
#include <sys/stat.h>
#include <sstream>
using namespace std;

int parseARGS(char **args, char *line){
int tmp=0;
args[tmp] = strtok( line, " /" );
while ( (args[++tmp] = strtok(NULL, " ,/" ) ) != NULL );
return tmp - 1;
}

void error(char *msg)
{
    perror(msg);
    exit(1);
}

int main(int argc, char *argv[])
{
     int sockfd, newsockfd, portNum, clilen;
     int nbytes=0;
     string line;
     char *header[4096];
     char *filename;	
     char buffer[1024];
     char filebuffer[4096];		 
     struct sockaddr_in serv_addr, cli_addr;
     int n;
     stringstream ss;


     if (argc < 2) {
         fprintf(stderr,"ERROR, no port provided\n");
         exit(1);
     }
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     if (sockfd < 0) 
        error("ERROR opening socket");
     portNum = atoi(argv[1]);
     serv_addr.sin_family = AF_INET;
     serv_addr.sin_addr.s_addr = INADDR_ANY;
     serv_addr.sin_port = htons(portNum);
     if (bind(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) 
              error("ERROR on binding");
     listen(sockfd,5);
     clilen = sizeof(cli_addr);
     while(1){
     newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t*)&clilen);
     ss.clear();
     if (newsockfd < 0) 
          error("ERROR on accept");
	n = read(newsockfd,buffer,1023);
       parseARGS(header, buffer);
       filename = header[1];
	int fileSize;
	struct stat fileStats;
	int status = stat(filename, &fileStats);
	fileSize = fileStats.st_size;
	char strfinal[fileSize+20];
	printf("Here is the message: %s\n",filename);
	if (n < 0) error("ERROR reading from socket");
       ifstream myfile(filename, ios::in|ios::binary);
  
	//read file and send
	if (myfile.is_open()) //if the file is open
	{	
		ss << "HTTP/1.0 200 OK \r\n\r\n";
		while (getline(myfile, line))
		{			
			ss << line;
			ss << "\n";
		}
		nbytes=send(newsockfd, ss.str().c_str(), ss.str().size(), 0);
              if(nbytes < 0) {
		    perror("send error");	
		    exit(1);
		}
	} 
       else{
		ss << "HTTP/1.0 404 FILE NOT FOUND \r\n\r\n";
		nbytes=send(newsockfd, ss.str().c_str(), ss.str().size(), 0);
		if(nbytes < 0) {
		    perror("send error");	
		    exit(1);
		}
	}
     ss.str( "" );
     close(newsockfd);            	
}
     return 0; 
}

better have the send only once:

when it's almost DRY ;)

//read file and send
	if (myfile.is_open()) //if the file is open
	{	
		ss << "HTTP/1.0 200 OK \r\n\r\n";
		while (getline(myfile, line))
		{			
			ss << line;
			ss << "\n";
		}
	} 
    else{
		ss << "HTTP/1.0 404 FILE NOT FOUND \r\n\r\n";
	}
	
	nbytes=send(newsockfd, ss.str().c_str(), ss.str().size(), 0);
	
	if(nbytes < 0) {
	    perror("send error");	
	    exit(1);
	}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.