Hi everyone :)
This is one of my first programs using C, so I am facing some issues.
our professer asked us to develop a TCP socket (client/server)
where the client sends lets say an ID,Name or Major and the server searches into a txt file and returns the line(s) that contain the info.

Example:
If Client (user) inputs: Nouf
printed to client screen: 20084, Nouf A, Computer Engineering

my only problem is that the server only reads the first line.
Example:
If Client (user) inputs: Computer Engineering
only this line is printed (returned from the search function): 20082, Noor F, Computer Engineering

even though it should return all the three lines:
20082, Noor F, Computer Engineering
20084, Nouf A, Computer Engineering
20103, Zainab S, Computer Engineering


So My problem is that the search function only returns the first line that relevant to the search and then it exits the search function..

My clients code:

/* tcpclient.c */


#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

int main()
{
        int sock, bytes_recieved;  
        char send_data[1024],recv_data[1024];
        struct hostent *host;
        struct sockaddr_in server_addr;  

        host = gethostbyname("127.0.0.1");

        if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) 
	{
            perror("Socket");
            exit(1);
	}
        server_addr.sin_family = AF_INET;     
        server_addr.sin_port = htons(5000);   
        server_addr.sin_addr = *((struct in_addr *)host->h_addr);
        bzero(&(server_addr.sin_zero),8); 

       if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) 
        
	{
                perror("Connect");
                exit(1);
       }

        
	while(1)
       
	 {
	printf("\n Enter Student ID or Name to view information (q or Q to quit) : ");
	gets(send_data);
              
        if (strcmp(send_data , "q") != 0 && strcmp(send_data , "Q") != 0)
	send(sock,send_data,strlen(send_data), 0); 

	else
          {             send(sock,send_data,strlen(send_data), 0);   
			close(sock);
          		break;
           }
        
               bytes_recieved=recv(sock,recv_data,1024,0);
               recv_data[bytes_recieved] = '\0';
 
          	printf("\nYour Search Result is: %s" , recv_data);
              	fflush(stdout);
		printf("\n");
 	}   
return 0;

}

Server Code:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int findName(char* clientSearch, char* serverResult);

int main()

{
        int sock, connected, bytes_recieved , true = 1;
  	char send_data [1024] , recv_data[1024], result[256];       
	struct sockaddr_in server_addr,client_addr;    
        int sin_size;
    
	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) 
	{
            perror("Socket");
	    exit(1);
	}
	if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(int)) == -1) 
	{
           perror("Setsockopt");
            exit(1);
	}
        
	server_addr.sin_family = AF_INET;         
	server_addr.sin_port = htons(5000);     
	server_addr.sin_addr.s_addr = INADDR_ANY; 
	bzero(&(server_addr.sin_zero),8); 

	if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))== -1) 
	{
            perror("Unable to bind");
	    exit(1);
        }

	if (listen(sock, 20) == -1) 
	{
 		perror("Listen");
            	exit(1);
       	}
        printf("\nTCPServer Waiting for client on port 5000");
        fflush(stdout);

//************************ end of create socket ***************
 while(1)
        
	{  
           sin_size = sizeof(struct sockaddr_in);
	   connected = accept(sock, (struct sockaddr *)&client_addr,&sin_size);
	    printf("\n I got a connection from (%s , %d)",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));

              while(1)
		{
			bytes_recieved = recv(connected,recv_data,1024,0);
			recv_data[bytes_recieved] = '\0';
			if (strcmp(recv_data , "q") == 0 || strcmp(recv_data , "Q") == 0)
              			{
					close(connected);
                                         break;
				 }

             		else 
 
            		 {	printf("\n Searching for.. %s \n" , recv_data);
             			fflush(stdout);

				findName(recv_data, result);
				send(connected, result,strlen(result), 0); 
			}
		}
		 
	}       
         close(sock);
         return 0;
} 


int findName(char* clientSearch, char* serverResult)
{
  FILE *filename=fopen("students1.TXT","r");
  char temp[256];
  bzero(temp,256);

 while (filename!=NULL && fgets(temp, sizeof(temp),filename) != NULL)

    {
      if (strstr(temp, clientSearch))
	{
	  strncpy(serverResult,temp, sizeof(temp));
	  return 1;
	}
	else
	strncpy(serverResult,"Does Not Exist", sizeof(temp));
	
    }
  if (filename!=NULL) fclose(filename);
  return 0;
}

My text file: students1.txt

20071, Frah W, Computer Science
20082, Noor F, Computer Engineering
20084, Nouf A, Computer Engineering
20105, Ala F, Interior Design
20103, Zainab S, Computer Engineering


Thank you very much for your help.

Noor

I don't want to solve your homework problems for you, but maybe I can point you in the right direction.

Your problem is that findName finds only the first matching line in the file and returns, correct? So you need to make findName somehow return as many lines as are in the file. There are three ways I can think of to go about this:

1) make findName concatenate all the lines in the file, and stuff them all into serverResult;

2) make findName return more than one line at once, by changing its prototype so that it can populate an array of lines rather than just one buffer;

3) make findName return a different line every time it's called, until there are no more lines left, and revise your calling code to repeatedly call findName until it indicates by a zero return value that there are no lines in the file.

I'd probably go for option 3, although option 1 might be less work. Look up strtok for a better idea of how such a function could behave.

I'd like to add, there is a very real potential for buffer overflow in the current program, which using option 1 would only aggravate; please consider passing the size of the result buffer in so findName won't accidentally write off the end of it.

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.