So basically I am creating a client/server kind of program. The client/user enters a question eg "Who are you? "
The server part receives this and checks it with a txt file and returns eg "I am a computer" or "Answer not found"

So when i compile and run my program, I type in the question but nothing else happens, the prompt just stays there and no output is seen.

My text file is something like this
What are you?:I am a computer.

#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 ;
    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 ;
	
    ifstream 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');
				
	vector<string> parts;
	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];
	
	}
	string tmpvar(recv_data);

        cout << "from " << inet_ntoa(client_addr.sin_addr)
                  << ':' << ntohs(client_addr.sin_port) << " - "
                  << recv_data << endl ;
	
	if (tmpvar == qns)
	cout << ans << endl;
	

    }
    return 0 ;
}

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

    sockaddr_in peer_addr ;
    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) ;

    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 ) ;
}

Dani AI

Generated

The code you posted never actually sends the answer back to the client — it only prints the answer on the server side. The client only calls sendto() and never waits for a reply, so from the client's point of view “nothing happens.” Fixes that will make this work reliably:

  • Have the server send the answer back to the client using the client_addr filled by recvfrom().
  • Have the client perform a recvfrom() (or recv()) after sendto() so it receives and prints the server’s reply.
  • Don’t parse the file inside the receive loop every time; load it once into a map at startup and look up requests.

Minimal snippets (illustrative — integrate into your loop):

/* server: after you compute `ans` and have client_addr/client_len */
ssize_t sent = sendto(socket_fd, ans.c_str(), ans.size(), 0,
                      (sockaddr*)&client_addr, client_len);
if (sent < 0) perror("sendto");
/* client: send then wait for reply */
ssize_t s = sendto(socket_fd, send_str.data(), send_str.size(), 0,
                   (sockaddr*)&peer_addr, sizeof(peer_addr));
if (s >= 0) {
  char rbuf[MSGSIZE];
  socklen_t peerlen = sizeof(peer_addr);
  ssize_t r = recvfrom(socket_fd, rbuf, sizeof(rbuf)-1, 0,
                       (sockaddr*)&peer_addr, &peerlen);
  if (r > 0) cout << "Server: " << string(rbuf, r) << endl;
}

Parse the Q/A file once (avoid strtok and repeated getline inside the loop):

unordered_map<string,string> answers;
ifstream f("file.txt");
string L;
while (getline(f, L)) {
  auto p = L.find(':');
  if (p == string::npos) continue;
  answers[L.substr(0,p)] = L.substr(p+1);
}

Other practical points: build string from the exact byte count returned by recvfrom() (string(buf, bytes_recd)), don’t resize(MSGSIZE) and send the whole fixed buffer (send only send_str.size()), use a local socklen_t client_len = sizeof(client_addr) (it’s overwritten by recvfrom), check and report bind() errors with perror, and consider running server and client as separate processes to simplify debugging. ’s suggestion to capture packets with Wireshark (or tcpdump) is useful if packets aren’t reaching the server.

1) make sure you are adding a \n to the end of the data stream (I've found it to work).
2) Install wireshark. Then you can sniff the traffic on that port, and check all incoming and outgoing (ehem) traffic.

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.