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

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.

This article has been dead for over six months. Start a new discussion instead.