Hi guys.

I would like to ask several questions about this. Im on my final phase of the proj, will appreciate some information.

Qn 1: How do i make the user continually input till he types 'exit' to exit?
Qn 2: If he types wrongly, or database couldnt find the result, should prompt for try again
Qn 3: How do i make the server accept multiple client connections? Meaning each client is able to display country data independently?

Would appreciate your answers. Heres my code

main prog

#include <stdlib.h>

#include <stdio.h>

#include <signal.h>

#include <string.h>

#include <sys/types.h>

#include <sys/socket.h>
#include "CountryData.h"

#include <sys/un.h>       /* for sockaddr_un struct */

#define DEFAULT_PROTOCOL   0



/* POSIX renames "Unix domain" as "local IPC."

    Not all systems define AF_LOCAL and PF_LOCAL (yet). */

#ifndef AF_LOCAL

#define AF_LOCAL    AF_UNIX

#endif

#ifndef PF_LOCAL

#define PF_LOCAL    PF_UNIX

#endif





/****************************************************************/

  main  ()

  {

    int serverFd, clientFd, serverLen, clientLen;

    struct sockaddr_un serverAddress;/* Server address */

    struct sockaddr_un clientAddress; /* Client address */

    struct sockaddr* serverSockAddrPtr; /* Ptr to server address */

    struct sockaddr* clientSockAddrPtr; /* Ptr to client address */



    /* Ignore death-of-child signals to prevent zombies */

    signal (SIGCHLD, SIG_IGN);



    serverSockAddrPtr = (struct sockaddr*) &serverAddress;

    serverLen = sizeof (serverAddress);



    clientSockAddrPtr = (struct sockaddr*) &clientAddress;

    clientLen = sizeof (clientAddress);



    /* Create a socket, bidirectional, default protocol */

    serverFd = socket (AF_LOCAL, SOCK_STREAM, DEFAULT_PROTOCOL);

    serverAddress.sun_family = AF_LOCAL; /* Set domain type */

    strcpy (serverAddress.sun_path, "recipe"); /* Set name */

    unlink ("recipe"); /* Remove file if it already exists */

    bind (serverFd, serverSockAddrPtr, serverLen); /* Create file */

    listen (serverFd, 5); /* Maximum pending connection length */
    char country1[256];
    char Capital[256];
    char Currency[100];
    int n;



    while (1) /* Loop forever */

      {

        /* Accept a client connection */

        clientFd = accept (serverFd, clientSockAddrPtr, &clientLen);



        if (fork () == 0) /* Create child to send recipe */

          {
          
          									

            if (clientFd < 0) 
          error("ERROR on accept");
          readData();
          
     bzero(country1,256);
     n = read(clientFd,country1,255);
     if (n < 0) error("ERROR reading from socket");
     
     
     
     
     
     
     printf("You have entered %s\n", country1);
	
	
	printf ("%s Capital       : %s\n", country1, getCapital (country1));
	printf ("%s Currency Code : %s\n", country1, getCurrencyCode (country1));
	 char* Capital = getCapital (country1);
	 char* Currency = getCurrencyCode(country1);
     
     
     
     n = write(clientFd,"Do you wish to try again?",255);
     if (n < 0) error("ERROR writing to socket");
     return 0; 
     
     

   close (clientFd); /* Close the socket */

   exit (/* EXIT_SUCCESS */ 0); /* Done */
   

          }

        else

          close (clientFd); /* Close the client descriptor */

      }

   }



   /****************************************************************/



   
   void readData ()
{
    FILE * pFile;
    NoOfRecordsRead = 0;
    char buffer [Line_Char_Buffer_Size];

    pFile = fopen (INPUT_FILE_NAME , "r");
   
    if (pFile == NULL) 
         perror ("Error opening file 'Countries.txt' !");
    else
    {
      while ( fgets(buffer, Line_Char_Buffer_Size,pFile) != NULL)
      {
        // printf ("%d] aLine => %s\n", NoOfRecordsRead, buffer);
         globalCountryDataArray [NoOfRecordsRead++] = createCountryRecord(buffer);
      }
      fclose (pFile);
    }
			
}





/******************************************************************************************************************/

CountryRecordType createCountryRecord (char* buffer)
{
	CountryRecordType ctryRec;
	char* pch = strtok (buffer, LINE_DATA_DELIMITER);

	// 1) Retrieve TLD
	strcpy (ctryRec.TLD, pch);
	pch = strtok (NULL, LINE_DATA_DELIMITER);

	// 2) Retrieve Country
	strcpy (ctryRec.Country, pch);
	pch = strtok (NULL, LINE_DATA_DELIMITER);

	// 3) Retrieve FIPS104
	strcpy (ctryRec.FIPS104, pch);
	pch = strtok (NULL, LINE_DATA_DELIMITER);

	// 4) Retrieve ISO2
	strcpy (ctryRec.ISO2, pch);
	pch = strtok (NULL, LINE_DATA_DELIMITER);

	// 5) Retrieve ISO3
	strcpy (ctryRec.ISO3, pch);
	pch = strtok (NULL, LINE_DATA_DELIMITER);

	// 6) Retrieve ISONo
	ctryRec.ISONo = atof (pch);
	pch = strtok (NULL, LINE_DATA_DELIMITER);

	// 7) Retrieve Capital
	strcpy (ctryRec.Capital, pch);
	pch = strtok (NULL, LINE_DATA_DELIMITER);

	// 8) Retrieve Region
	strcpy (ctryRec.Region, pch);
	pch = strtok (NULL, LINE_DATA_DELIMITER);

	// 9) Retrieve Currency
	strcpy (ctryRec.Currency, pch);
	pch = strtok (NULL, LINE_DATA_DELIMITER);

	// 10) Retrieve CurrencyCode
	strcpy (ctryRec.CurrencyCode, pch);
	pch = strtok (NULL, LINE_DATA_DELIMITER);

	// 11) Retrieve Population
	ctryRec.Population = atof (pch);

	return (ctryRec);
	}

/****************************************************************************************************************/

void displayRecordContent (CountryRecordType ctryRec)
{
	printf ("TLD			: %s\n", ctryRec.TLD);
	printf ("Country		: %s\n", ctryRec.Country);
	printf ("FIPS104		: %s\n", ctryRec.FIPS104);
	printf ("ISO2			: %s\n", ctryRec.ISO2);
	printf ("ISO3			: %s\n", ctryRec.ISO3);
	printf ("ISONo			: %lf\n", ctryRec.ISONo);
	printf ("Capital		: %s\n", ctryRec.Capital);
	printf ("Region			: %s\n", ctryRec.Region);
	printf ("Currency		: %s\n", ctryRec.Currency);
	printf ("CurrencyCode	: %s\n", ctryRec.CurrencyCode);
	printf ("Population		: %lf\n\n", ctryRec.Population);
}

int findCountryRecord (const char* countryName)
{
	int idx		= -1;
	int found	= 0;

	while (!found && (++idx < Max_Record_Size))
		if (strcmp (globalCountryDataArray [idx].Country, countryName) == 0)
			found = 1;
			

	if (found)
		return (idx);
	else
	
		return (-1);
}

// ====================================================================

char* getCapital (const char* countryName)
{
	int idx = findCountryRecord (countryName);

	if (idx < 0)
	{
		printf ("Error! Country '%s' not found\n", countryName);
		return (NULL);	
	}
	else
		return (globalCountryDataArray [idx].Capital);
}

// ====================================================================

char* getCurrencyCode (const char* countryName)
{
	int idx = findCountryRecord (countryName);

	if (idx < 0)
	{
		printf ("Error Country '%s' not found\n", countryName);
		return (NULL);	
	}
	else
		return (globalCountryDataArray [idx].CurrencyCode);
}

client

#include <stdlib.h>

#include <stdio.h>

#include <signal.h>

#include <string.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <sys/un.h>            /* for sockaddr_un struct*/

#define DEFAULT_PROTOCOL    0



/* POSIX renames "Unix domain" as "local IPC."

    Not all systems define AF_LOCAL and PF_LOCAL (yet). */

#ifndef AF_LOCAL

#define AF_LOCAL    AF_UNIX

#endif

#ifndef PF_LOCAL

#define PF_LOCAL    PF_UNIX

#endif



/****************************************************************/

 main  ()

 {

   int clientFd, serverLen, result;

   struct sockaddr_un serverAddress;

   struct sockaddr* serverSockAddrPtr;

   serverSockAddrPtr = (struct sockaddr*) &serverAddress;

   serverLen = sizeof (serverAddress);



   /* Create a socket, bidirectional, default protocol */

   clientFd = socket (AF_LOCAL, SOCK_STREAM, DEFAULT_PROTOCOL);

   serverAddress.sun_family = AF_LOCAL; /* Server domain */

   strcpy (serverAddress.sun_path, "recipe"); /* Server name */
   char country1[256];
   int n;

   do /* Loop until a connection is made with the server */

     {

       result = connect (clientFd, serverSockAddrPtr, serverLen);

       if (result == -1) sleep (1); /* Wait and then try again */

     }

   while (result == -1);
   

   printf("Please enter country name: ");
    scanf("%s",country1);
   
    n = write(clientFd,country1,strlen(country1));
    if (n < 0) 
         error("ERROR writing to socket");
    bzero(country1,256);
    n = read(clientFd,country1,256);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",country1);
    return 0;
    /* Send the recipe */

          if (country1 == "1"){  close (clientFd); /* Close the socket */

            exit (/* EXIT_SUCCESS */ 0); }/* Terminate */

 }

 /**************************************************************/

Additional Lib

#ifndef COUNTRY_DATA_H
#define COUNTRY_DATA_H

// ====================================================================

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

// ====================================================================

#define TLD_LEN				2
#define COUNTRY_LEN 		100
#define FIPS104_LEN 		2
#define ISO2_LEN			2
#define ISO3_LEN			3
#define CAPITAL_LEN			100
#define REGION_LEN			100
#define CURRENCY_LEN		50
#define CURRENCY_CODE_LEN	3

#define No_Of_Rec_Fields		11
#define Max_Record_Size			2500
#define Line_Char_Buffer_Size	4000

#define LINE_DATA_DELIMITER 	","
#define INPUT_FILE_NAME 		"Countries.txt"

// ====================================================================

//const char*	LINE_DATA_DELIMITER		= ",";
//const char*	INPUT_FILE_NAME 		= "Countries.txt";


typedef struct CountryRecord
{
	char TLD			[TLD_LEN+1];			// Top Level Domain code
	char Country		[COUNTRY_LEN+1];	
	char FIPS104		[FIPS104_LEN+1];		// Ctry code according to FIPS104 standard
	char ISO2			[ISO2_LEN+1];			// Ctry code according to ISO2    standard
	char ISO3			[ISO3_LEN+1];			// Ctry code according to ISO3    standard
	double ISONo;

	char Capital		[CAPITAL_LEN+1];	
	char Region			[REGION_LEN+1];			// E.g. Asia, Europe, etc.
	char Currency		[CURRENCY_LEN+1];		// Full name of currency
	char CurrencyCode	[CURRENCY_CODE_LEN+1];	// Currency abbreviation
	double Population;

}	CountryRecordType;


int NoOfRecordsRead;
CountryRecordType globalCountryDataArray [Max_Record_Size];

// ====================================================================

void readData ();
char* get_line (char *s, size_t n, FILE *f);
CountryRecordType createCountryRecord (char* aLine);
void displayRecordContent (CountryRecordType ctryRec);
void showAllRecords ();

int findCountryRecord (const char* countryName);
char* getCapital (const char* countryName);
char* getCurrencyCode (const char* countryName);

// ====================================================================

#endif // COUNTRY_DATA_H

finally Countries.txt

SZ,Swaziland,WZ,SZ,SWZ,748.00,Mbabane,Africa,Lilangeni,SZL,1104343.00
TC,Turks and Caicos Islands,TK,TC,TCA,796.00,Cockburn Town,Central America and the Caribbean,US Dollar,USD,18122.00
TD,Chad,CD,TD,TCD,148.00,N'Djamena,Africa,CFA Franc BEAC,XAF,8707078.00
TF,French Southern and Antarctic Lands,FS,TF,ATF,260.00,--,Antarctic Region,Euro,EUR,0.00
TG,Togo,TO,TG,TGO,768.00,Lome,Africa,CFA Franc BCEAO,XOF,5153088.00
TH,Thailand,TH,TH,THA,764.00,Bangkok,Southeast Asia,Baht,THB,61797751.00
TJ,Tajikistan,TI,TJ,TJK,762.00,Dushanbe,Commonwealth of Independent States,Somoni,TJS,6578681.00
TK,Tokelau,TL,TK,TKL,772.00,--,Oceania,New Zealand Dollar,NZD,1445.00
TM,Turkmenistan,TX,TM,TKM,795.00,Ashgabat,Commonwealth of Independent States,Manat,TMM,4603244.00
TN,Tunisia,TS,TN,TUN,788.00,Tunis,Africa,Tunisian Dinar,TND,9705102.00
TO,Tonga,TN,TO,TON,776.00,Nuku'alofa,Oceania,Pa'anga,TOP,104227.00
TP,East Timor,TT,TL,TLS,626.00,--, ,Timor Escudo,TPE,
TR,Turkey,TU,TR,TUR,792.00,Ankara,Middle East,Turkish Lira,TRL,66493970.00
TT,Trinidad and Tobago,TD,TT,TTO,780.00,Port-of-Spain,Central America and the Caribbean,Trinidad and Tobago Dollar,TTD,1169682.00
Member Avatar for andylbh

Thread-necroing this.

I've no problem with forking to accept multiple client and user inputs 'end' to end the program.

I'm currently this problem:
How do I loop send() and recv() so the server running the background will continue sending data when client writes to it?
I searched around and found out that I'm not supposed to close(clientFd) because it will terminate any incoming send/recv.
Even so, my program is not responding to second send() or recv() , but only respond to 'end' which terminates the program.

Help is very much appreciated.
Thanks in advance.

How did you solve the user continually input till he types 'exit' to exit?

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.