So, what Im trying to do here is a client server socket program. The client will ask a question to the server. For example, How are you?
Then the server opens a text file, compares the string from the client and outputs the answer to the client.

My text file is something like this.
How are you? I am fine.

so client asks How are you?
server outputs to client I am fine.

So far I have tried compiling my code and there seems to be a compilation error. If I do not include the file reading and string checking, the client/server socket code works fine. As in I can make the server repeat whatever the client inputs.

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <iostream>
#include <cstring>
#include <string>
#include <fstream>
#include <vector>
#include <cstdlib>
#include <iostream>
using namespace std;

enum { RECV_PORT = 5000, MSGSIZE = 1024 };
const char fileName[30] = "file.txt";
char* s;
char input[255];
char* result = NULL;
string qns, ans;
socklen_t addr_len = sizeof(sockaddr) ;

int server( int socket_fd )
{
    sockaddr_in my_addr ;
    std::memset( &my_addr, 0, sizeof(my_addr) ) ;
    my_addr.sin_family = AF_INET ;
    my_addr.sin_port = htons( RECV_PORT ) ;
    my_addr.sin_addr.s_addr = INADDR_ANY ;

    if ( bind( socket_fd, (sockaddr*)&my_addr, addr_len ) != 0 )
       return 2 ;
	
    fstream infile(fileName);
    while( true )
    {
	infile.open(fileName);
			
        char recv_data[MSGSIZE+1] ;
        sockaddr_in client_addr ;

        int bytes_recd = recvfrom( socket_fd, recv_data, MSGSIZE, 0,
                                (sockaddr*)&client_addr, &addr_len ) ;
        if( bytes_recd == -1 ) 
	break ;
	
	else
	recv_data[bytes_recd] = '\0' ;
	
	{	
		infile.getline(input,255, '\n');
		
		while(!infile.eof())
		{
		
			vector<string> parts;
			std::string tmpstr(input);
			s = input;	

			result = strtok(s, " ");

			while (result != NULL)  
			{
				if (result != "" && result != "?.!") 
				{
					parts.push_back(result);
				}

         			result = strtok(NULL, "?.!");
     		}
		
		qns = parts[0];
		ans = parts[1];
		
		if (recv_data.compare(qns)==0)
		std::cout << ans << std::endl;
		}
		
	
	}	
	
        std::cout << "from " << inet_ntoa(client_addr.sin_addr)
                  << ':' << ntohs(client_addr.sin_port) << " - "
                  << recv_data << std::endl ;
    }
    return 0 ;
}

int client( int socket_fd )
{
    std::cout << "Enter Address to connect: " ;
    std::string address ; std::cin >> address >> std::ws ;

    sockaddr_in peer_addr ;
    std::memset( &peer_addr, 0, sizeof(peer_addr) ) ;
    peer_addr.sin_family = AF_INET ;
    peer_addr.sin_port = htons( RECV_PORT ) ;
    peer_addr.sin_addr.s_addr =
             *(in_addr_t*)(gethostbyname( address.c_str() )->h_addr) ;

    std::string send_str ;
    while( std::getline( std::cin, send_str ) )
    {
      send_str.resize(MSGSIZE) ;
      sendto( socket_fd, send_str.c_str(), MSGSIZE, 0,
            (sockaddr*)&peer_addr, addr_len ) ;
    }
    return 0 ;
}

int main()
{
	



  int socket_fd = socket( AF_INET, SOCK_DGRAM, 0 ) ;
  if( socket_fd == -1 ) return 1 ;
  return fork() == 0 ? server( socket_fd ) : client( socket_fd ) ;
}

Recommended Answers

All 8 Replies

First... I wouldn't make the text file in that way. I'd use a delimiter. Such as:

Hello, How are you?:I'm fine.

This saves you the hassle of having to guess where the client sentence ends and the server sentence should begin. You already know... it's because of the :. I suppose the same could be said about the ?, but what if it now becomes a statement? Using a standard delimiter makes life that much easier.
As far as the code goes... it looks to me like your second strtok might throw things off result = strtok(NULL, "?.!"); doesn't match up with your first strtok, which is splitting by " ", not ?.!. You said above that there seems to be a compilation error... if so, what is the error?

the error is the recv_data type is not the same as my vector strings (qns and ans). So I am unable to string compare. And this is kind of a problem for me

ah, yes. You could take the char array, and convert it to string, and then compare. While a bit of a pain I suppose:

std::string tmpvar(recv_data);
if (tmpvar.compare(qns) == 0)

I think you could just do a simple == at that point though. if (tmpvar == qns) {

ok so now my code compiles properly. However, it doesnt work. I am able to input a question like How are you?
but nothing else happens. It should be able to create a fork and the server side of my code should be comparing the input with the file and displaying the answer.
Is there anything wrong with my file reading loop?

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <iostream>
#include <cstring>
#include <string>
#include <fstream>
#include <vector>
#include <cstdlib>
#include <iostream>
using namespace std;

enum { RECV_PORT = 5000, MSGSIZE = 1024 };
const char fileName[30] = "file.txt";
char* s;
char input[255];
char* result = NULL;
string qns, ans;
socklen_t addr_len = sizeof(sockaddr) ;

int server( int socket_fd )
{
    sockaddr_in my_addr ;
    std::memset( &my_addr, 0, sizeof(my_addr) ) ;
    my_addr.sin_family = AF_INET ;
    my_addr.sin_port = htons( RECV_PORT ) ;
    my_addr.sin_addr.s_addr = INADDR_ANY ;

    if ( bind( socket_fd, (sockaddr*)&my_addr, addr_len ) != 0 )
       return 2 ;
	
    fstream infile(fileName);
    while( true )
    {
	infile.open(fileName);
			
        char recv_data[MSGSIZE+1] ;
        sockaddr_in client_addr ;

        int bytes_recd = recvfrom( socket_fd, recv_data, MSGSIZE, 0,
                                (sockaddr*)&client_addr, &addr_len ) ;
        if( bytes_recd == -1 ) 
	break ;
	
	else
	recv_data[bytes_recd] = '\0' ;
	
	{	
		infile.getline(input,255, '\n');
		
		while(!infile.eof())
		{
		
			vector<string> parts;
			std::string tmpstr(input);
			s = input;	

			result = strtok(s, ":");

			while (result != NULL)  
			{
				if (result != "" && result != ":") 
				{
					parts.push_back(result);
				}

         			result = strtok(NULL, ":");
     		}
		
		qns = parts[0];
		ans = parts[1];

		std::string tmpvar(recv_data);

		if (tmpvar == qns)
		std::cout << ans << std::endl;
		}
		
	
	}	
	/*=====echo recv_data=====
        std::cout << "from " << inet_ntoa(client_addr.sin_addr)
                  << ':' << ntohs(client_addr.sin_port) << " - "
                  << recv_data << std::endl ;*/
    }
    return 0 ;
}

int client( int socket_fd )
{
    std::cout << "Enter Address to connect: " ;
    std::string address ; std::cin >> address >> std::ws ;

    sockaddr_in peer_addr ;
    std::memset( &peer_addr, 0, sizeof(peer_addr) ) ;
    peer_addr.sin_family = AF_INET ;
    peer_addr.sin_port = htons( RECV_PORT ) ;
    peer_addr.sin_addr.s_addr =
             *(in_addr_t*)(gethostbyname( address.c_str() )->h_addr) ;

    std::string send_str ;
    while( std::getline( std::cin, send_str ) )
    {
      send_str.resize(MSGSIZE) ;
      sendto( socket_fd, send_str.c_str(), MSGSIZE, 0,
            (sockaddr*)&peer_addr, addr_len ) ;
    }
    return 0 ;
}

int main()
{
	



  int socket_fd = socket( AF_INET, SOCK_DGRAM, 0 ) ;
  if( socket_fd == -1 ) return 1 ;
  return fork() == 0 ? server( socket_fd ) : client( socket_fd ) ;
}

Without looking through all your code, I see this thing:

else
	recv_data[bytes_recd] = '\0' ;
	
	{
                 infile.getline(input,255, '\n');
		
		while(!infile.eof())

What is that brace doing there? That code block will always be executed, because the {}-block isn't part of any if/else/while/for block.

hmm i removed those braces and got the same results as I posted before.

What I meant was: the braces are in the wrong place. The open brace should be directly after 'else'. How much experience do you have with c/c++? Perhaps you might want to read up on a if/else tutorial

forgot to mention that in my above post, but i tried putting the braces as you advised too. Both removing and changing the position of the braces resulted in the program doing nothing. Im not new to if else....
I am new to this socket and not sure how to integrate a file read/manipulation with the server part. As I said the echoing of input is fine. I believe it's the file read which makes my program not work but I don't know which part of the logic is wrong.

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.