Thread: Client/Server

  1. #1
    Registered User
    Join Date
    Dec 2005
    Posts
    29

    Client/Server

    Hi, me AGAIN!

    Having trouble getting an integer sent from my client to my server...everything compiles nicely, but nothing seems to be getting recieved....

    As soon as I can get some data being sent back and forth, I am well way...

    Client Code

    Code:
    /*Socket*/
    
    #include<stdio.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    
    int sd;
    
    int main(int argc,char** argv)
    {
    
    	int a = 0;	
    
    	sd = socket(AF_INET, SOCK_STREAM,0);
    /*End of Socket*/			
    
    	/*Client*/
    	struct sockaddr_in servaddr;
    
    	bzero(&servaddr,sizeof(servaddr));
    	servaddr.sin_family = AF_INET; //Set the domain
    	servaddr.sin_port = htons(atoi(argv[2])); //The port to connect to 
    	inet_aton(argv[1],&servaddr.sin_addr); //THe IP address of the server machine.
    
    //e.g Client   127.0.0.1   5000
    
    	connect(sd,(struct sockaddr*)&servaddr,sizeof(servaddr)); 
    
    	
    	printf("Please enter the integer you wish to send ");	
    	scanf("%d",  &a);
    	send(sd, &a, sizeof(a), 0);
    
    	/*End of Client*/
    }
    
    
    
    //SOCK_STREAM creates a realiable two-way connection
    //AF_INET specifies IPv4 Internet protocols
    //s is the descriptor (sd)
    //buf is the data to send (e.g a string)
    //len is the length of data sent
    //flags are the options(in this case can be 0).
    This is my server
    Code:
    /*Socket*/
    #include<stdio.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    
    int sd = 0;
    
    int main(int argc,char** argv)
    {
    	int connfd = 0;
    	int listenfd = 0;
    	size_t clilen;
    	int recv_data = 0; //recieving integer data
    	
    	sd = socket(AF_INET, SOCK_STREAM,0); //Creating New Socket
    	
    
    	listenfd = sd;//Did this as listenfd has not been defined yet 
    /*End of Socket*/			
    
    	/*Server*/
    	struct sockaddr_in servaddr; //Creating buffer
    
    	bzero(&servaddr,sizeof(servaddr)); //Sets all values in buffer to zero
    	servaddr.sin_family = AF_INET; //Sets the domain
    	servaddr.sin_addr.s_addr = htonl(INADDR_ANY); //Accepting connections from any machine
    	servaddr.sin_port = htons(atoi(argv[1])); //First argument, e.g Server 50,000 uses port 50,000
    
    	bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr)); //Binds a socket to an address
    	listen(listenfd,10); //Accepts 10 clients to connect
    
    int store;
    //infinite for loop HERE
    //used to accept connections from client
    	for(;;) {
    	struct sockaddr_in cliaddr;
    	connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&clilen); //-1 if nothing is being received
    	store = recv(sd, &recv_data, sizeof(recv_data), 0);
    	if (connfd != -1)
    	{
    		printf("%d", store);
    	}
    	/*End of Client*/		
    	}
    
    }
    
    
    
    //SOCK_STREAM creates a realiable two-way connection
    //AF_INET specifies IPv4 Internet protocols
    //listenfd is a descriptor for the servers socket(intiated when creating the socket)


    I assume that when I return information back from the server, I 'send' from the server, and 'recv' at the client...

    Does this mean I'd need another infinite for loop at the client, always checking wther information is being sent back or not?

    Thanks
    Last edited by zonf; 12-14-2005 at 09:50 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > store = recv(sd, &recv_data, sizeof(recv_data), 0);
    > if (connfd != -1)
    > printf("%d", store);
    Your data is in recv_data.
    How many bytes you received is in store.

    If the number of bytes isn't what you expected, then you need to call recv again (and again) until you have all the bytes you expect (messages can fragment, and it's down to you to reassemble them).

  3. #3
    Registered User
    Join Date
    Dec 2005
    Posts
    29
    Hi, for some completely stupid unknown reason, my server code won't printf() anything.....

    to test this, I have put a printf("test") at the beginning.....and this is not being printed, yet the code is still being run and sends information to the client....this is driving me mad.....

    Code:
    #include<stdio.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    
    int main(int argc,char** argv)
    {
    
    
    	printf("Test");
    
    
    	int connfd = 0;
    	int listenfd = 0;
    	size_t clilen;   //this had not been initialized.
    	char recv_char_data[128];
    	listenfd = socket(AF_INET, SOCK_STREAM,0); //Creating New Socket
    	struct sockaddr_in servaddr; //Creating buffer
    
    	bzero(&servaddr,sizeof(servaddr)); //Sets all values in buffer to zero
    	servaddr.sin_family = AF_INET; //Sets the domain
    	servaddr.sin_addr.s_addr = htonl(INADDR_ANY); //Accepting connections from any machine
    	servaddr.sin_port = htons(atoi(argv[1])); //First argument, e.g Server 50,000 uses port 50,000
    
    	bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr)); //Binds a socket to an address
    	listen(listenfd,10); //Accepts 10 clients to connect
    	
    
    struct sockaddr_in cliaddr, clilen_in;
    clilen = sizeof(clilen_in);  //This was the most important bit, this is the bit that you discovered
    
    printf("Server Connected");
    
    //infinite for loop HERE
    //used to accept connections from client
    
    	for(;;) 
    	{
    		connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&clilen); //-1 if nothing is being received
    		
    		recv(connfd, &recv_char_data, sizeof(recv_char_data), 0);	
    		if (connfd != -1)
    		{
    			printf("%s", recv_char_data);	
    			send(connfd, "Transaction Complete", 21, 0);
    		}
    						
    	}
    
    }

  4. #4
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    The stdout stream isn't necessarily flushed until you send a '\n', or you flush it with fflush().

    Try changing
    Code:
    printf("Test");
    to
    Code:
    printf("Test\n");
    or to
    Code:
    printf("Test");
    fflush(stdout);

  5. #5
    Registered User
    Join Date
    Dec 2005
    Posts
    29
    Thanks very much , it's been insanely frustrating !!!

  6. #6
    Registered User
    Join Date
    Dec 2005
    Posts
    29
    I'm passing an instruction to the server in the form of a single char....W would represent for example 'Withdrawl'.

    Now, I don't understand what is wrong with the bolded line......I'm comparing the first value in the char array with the char 'W'....the code inside that if isn't being run.

    My next problem, is that I then want to recieve another command after having entered that if statement. Say 'Ten' is passed...I've got no idea how to recieve another instruction, but from within that if statement....I thought an infinite for loop might work, constantly waiting for another instruction, but I can't even get that far....

    I just need to grasp these two things and I am well away...


    Code:
                            recv(connfd, &recv_char_data, sizeof(recv_char_data), 0);
    			printf("Instruction Received :: %c :: from %d\n", recv_char_data[0], connfd);
    			fflush(stdout);
    
    			if(recv_char_data[0] == 'W')
    			{
    				for(;;) 
    				{	 	
    					recv(connfd, &recv_char_data, sizeof(recv_char_data), 0);
    				}
    			}

  7. #7
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    You aren't guaranteed that 2 sends will equal 2 recvs. Both sends could very likely be in your receive data after the first recv() call.
    If you understand what you're doing, you're not learning anything.

  8. #8
    Registered User
    Join Date
    Dec 2005
    Posts
    29
    I now only need to take one recieve off the user, that's on the server side. When I try and 'send' more than once from the server to the client, it doesn't work.

    I'm assuming I have a problem with the 'recv' on the client side....how do I recieve more than one' send'?

    (both of the 'send's aren't stored in the one 'recv' on the client side, the second one goes missing...)

  9. #9
    Registered User
    Join Date
    Dec 2005
    Posts
    29
    Right, hello everyone again....I'm making some progress now...

    With the 'Pushes' still left in the server, the output returned to the client is aload of gibberish....

    Is there anything that anyone can see that is completely wrong with my code? I'll include my stack, server and client:

    STACK :
    Code:
    #include<stdio.h>
    
    #include"stack.h"
    
    
    
    struct store{
    	int data_int;
    	char data_char;
    	int num;
    } peeking;
    
    stack_t* stack;  		
    
    int stack_size;
    
    void push(int d_int, char d_char, stack_t **stackptr)   			//Pushes integer onto the stack
    
    {
    
    	stack_t* push_element; 						//Stack pointer
    
                    
    
    	push_element = (stack_t*)  malloc(sizeof(stack_t));	//Allocating memory 		
    
    	push_element->data_int = d_int;
    	push_element->data_char = d_char;  					//Data assigned
    
    	push_element->next = (*stackptr);				//Next is now equal to the address  [which is of type pointer ]  that stackptr  [pointer to a pointer]  points to.  
    
    	(*stackptr) = push_element;   				//Address stackptr points to now stores new_element
    
    	stack_size++;							//Increment stack size, as integer has been pushed
    
    }
    
    
    
    void pop(stack_t **stackptr)						//Pop integer off the stack
    
    {
    
    	int d_int;
    	char d_char;								//Used to store data
    
    	stack_t* pop_element;						//Stack pointer
    
    	if (stack_size != 0)						//If stack is not empty
    
    	{
    
    		pop_element = (*stackptr);       			//pop_element is now equal to the address  [which is of type pointer ]  that stackptr  [pointer to a pointer]  points to.  	
    
          	d_int = pop_element->data_int;
    	d_char = pop_element->data_char;
    		    			//Data is copied 
    
    		(*stackptr) = pop_element->next;  			//Stackptr now points to pop_element->next.              
    
    		free(pop_element); 		     			//Remove pointer after usage.
    
    		stack_size--;						//Decrement stack size, as integer has been popped.					
    
    	}
    
    }
    
    
    
    struct store peek(stack_t **stackptr, int size)				//Displays all values in the stack
    
    {
    
    	stack_t* peek_element;						//Stack pointer
    
    	stack_t* store_element;						//Stack pointer	
    
    	int i;	
    	int d_int;
    	char d_char;
    	store_element = (*stackptr);					//Stack pointer stores address that *stackptr points to.
    
    	printf("Peeking at stack:: ");			
    
    	for ( i=0; i < size; i++)					//Loop untill i = stack size.
    
    	{
    
    		peek_element = (*stackptr);       			//Peek_element is now equal to the address  [which is of type pointer ]  that stackptr  [pointer to a pointer]  points to.  	
    
          		peeking.data_int = peek_element->data_int;
    		peeking.data_char = peek_element->data_char; 	    			//Data is copied 
    
    		(*stackptr) = peek_element->next;			//Stackptr now points to peek_element->next 
    
    						//Prints value of data
    
    	}
    	return peeking;	//Returns  value at top of stack
    
    	printf("\n");							//New line
    
    	(*stackptr) = store_element;					//*stackptr now points to store_element, restoring it's orginal value.
    
    }

    SERVER:

    Code:
    #include<stdio.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<string.h>
    #include"stack.h"
       struct receive_data {
    		 char command;
                     int int_part;
    		 int id_part;
             } recv_data;
    
      struct send_data {
    		char char_data[128];
    		int int_data;
    	} s_data;
    
       struct user {
    		int id;
    		int total;
    		int transaction;
    	        stack_t *stack;
    	      }my_user[3];
    
    	struct store{
    		int data_int;
    		char data_char;
    		int num;
      		};
    int withdraw(int num, int withdrawl_cash);
    int deposit(int num, int deposit_cash);
    
    
    
    
    int main(int argc,char** argv)
    {
    	int i;
    	int k = 0;
    	int connfd = 0;
    	int listenfd = 0;
    	size_t clilen;   //this had not been initialized.
    	char send_char[128];
    	char trans[22] = "Transaction Completed";
    	
    
    	listenfd = socket(AF_INET, SOCK_STREAM,0); //Creating New Socket
    	struct sockaddr_in servaddr; //Creating buffer
    
    	bzero(&servaddr,sizeof(servaddr)); //Sets all values in buffer to zero
    	servaddr.sin_family = AF_INET; //Sets the domain
    	servaddr.sin_addr.s_addr = htonl(INADDR_ANY); //Accepting connections from any machine
    	servaddr.sin_port = htons(atoi(argv[1])); //First argument, e.g Server 50,000 uses port 50,000
    
    	bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr)); //Binds a socket to an address
    	listen(listenfd,10); //Accepts 10 clients to connect
    	
    
    	struct sockaddr_in cliaddr, clilen_in;
    	clilen = sizeof(clilen_in);  //This was the most important bit, this is the bit that you discovered
    
    	printf("*Server Connected*\n");
    
    
    
    //Initializing data for testing purposes (assuming that server will constantly be running, this data would be readily avaliable to the customers)
    
    	my_user[0].id = 0000;
    	my_user[0].total = 10;
    	
    	my_user[1].id = 1111;
    	my_user[1].total = 20;
    	
    	my_user[2].id = 2222;
    	my_user[2].total = 30;
    	
    	my_user[3].id = 3333;
    	my_user[3].total = 40;
    	
    	my_user[4].id = 4444;
    	my_user[4].total = 0;
    //infinite for loop HERE
    //used to accept connections from client
    
    	for(;;) 
    	{
    		connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&clilen); //-1 if nothing is being received
    		
    		
    		if (connfd != -1)
    		{
    			recv(connfd, &recv_data, sizeof(recv_data), 0);
    			printf("\n\nInstruction Received :: %c ::\n", recv_data.command);
    			printf("Value Received :: %d ::\n", recv_data.int_part);	
    			fflush(stdout);	
    
    			if(recv_data.command == 'W')
    			{
    				for (i = 0; i < 4; i++)
    				{
    					if (my_user[i].id == recv_data.id_part)
    					{	
    						k = i;
    						printf("\nUser Number %d", k);
    						my_user[k].transaction++;
    						push(recv_data.int_part,recv_data.command,&my_user[k].stack);   
    					}
    				} 
    				s_data.int_data = withdraw(k,recv_data.int_part);
    				strcpy(s_data.char_data,trans);
    				send(connfd, &s_data, sizeof(s_data),0);		
    			} 
    			else if (recv_data.command == 'D')
    			{
    				for (i = 0; i < 4; i++)
    				{
    					if (my_user[i].id == recv_data.id_part)
    					{	
    						k = i;
    						printf("\nUser Number %d", k);
    						my_user[k].transaction++;
    						push(recv_data.int_part,recv_data.command,&my_user[k].stack);  
    					}
    				} 	
    				s_data.int_data = deposit(k,recv_data.int_part);;
    				strcpy(s_data.char_data,trans);
    				send(connfd, &s_data, sizeof(s_data),0);
    		      	}
    			else if (recv_data.command == 'C')
    			{
    				for (i = 0; i < 4; i++)
    				{
    					if (my_user[i].id == recv_data.id_part)
    					{	
    						k = i;
    						printf("\nUser Number %d", k);
    						my_user[k].transaction++;
    						push(recv_data.int_part,recv_data.command,&my_user[k].stack);  
    					}
    				} 
    				s_data.int_data = my_user[k].total;
    				strcpy(s_data.char_data,trans);
    				send(connfd, &s_data, sizeof(s_data),0);
    			} 
    			else if(recv_data.command == 'M')
    			{  
    				for (i = 0; i < 4; i++)
    				{
    					if (my_user[i].id == recv_data.id_part)
    					{	
    						k = i;
    						printf("\nUser Number %d", k);
    						my_user[k].transaction++;
    						push(recv_data.int_part,recv_data.command,&my_user[k].stack);  
    					}
    				}
    				
      				struct store test[my_user[k].transaction];
    				for (i=my_user[k].transaction; i > 0 ; i--)
    				{
    					test[i] = peek(&my_user[k].stack, i);
    				}
    				
    				send(connfd, &test, sizeof(test),0);
    			} 	
    
    
    
    		}
    
    	
    	}
    				
    }
    
    
    
    int withdraw(int num, int withdrawl_cash)
    {
    	printf("\nBefore Withdrawl - %d",my_user[num].total);
    	my_user[num].total = (my_user[num].total - withdrawl_cash);
    	printf("\nAfter Withdrawl - %d",my_user[num].total);
    	return my_user[num].total;
    }	
    
    int deposit(int num, int deposit_cash)
    {
    	printf("\nBefore Deposit - %d",my_user[num].total);
    	my_user[num].total = (my_user[num].total + deposit_cash);
    	printf("\nAfter Deposit - %d",my_user[num].total);
    	return my_user[num].total;
    }
    CLIENT:

    Code:
    #include<stdio.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    
       struct send_data {
    		 char command;
                     int int_part;
    		 int id_part;
             } my_data;
    
       struct store{
    	int data_int;
    	char data_char;
    	int num;
    	}recv_mini[100];
    	
    int sd;
    
    
    int main(int argc,char** argv)
    {
    	sd = socket(AF_INET, SOCK_STREAM,0);	
    
    	struct sockaddr_in servaddr;
    	char recv_data[128];
    	int recv_data_int;
            int e,p,i;
    	char a;
    
    	bzero(&servaddr,sizeof(servaddr));
    	servaddr.sin_family = AF_INET; //Set the domain
    	servaddr.sin_port = htons(atoi(argv[2])); //The port to connect to 
    	inet_aton(argv[1],&servaddr.sin_addr); //THe IP address of the server machine.
    
    	connect(sd,(struct sockaddr*)&servaddr,sizeof(servaddr)); 
    			
    	printf("\n*Client Connected*\n");
    	fflush(stdout);
    	
    	printf("\nPlease enter your pin number\n");
    	scanf("%d", &p);
    	my_data.id_part = p;
    
    	printf("\nWhich action would you like?\n\n	Withdraw(W)\n	Deposit(D)\n	Check Balance(C)\n	Mini Statement(M)\n	Quit(Q)\n\n: ");
    	scanf("%s", &a);
    	my_data.command = a;
    
    
    	switch(a)
    	{
    		case 'W' : printf("\nHow much would you like to withdraw?\n\n::10::     ::20::\n::30::     ::40::\n::50::     ::100::\n::150::    ::200::\n:"); 
    				   
    			scanf("%d", &e);
    			my_data.int_part = e;		
    			send(sd, &my_data, sizeof(my_data), 0); 
    			recv(sd, &recv_data, sizeof(recv_data), 0);
    			printf("%s\n", recv_data);
    			fflush(stdout);
    			break;
    			
    
    
    
    		case 'D' : printf("\nHow much would you like to deposit?\\n\n::10::     ::20::\n::30::     ::40::\n::50::     ::100::\n::150::    ::200::\n:");
    			   scanf("%d", &e);
    			   my_data.int_part = e;
    			   send(sd, &my_data, sizeof(my_data), 0); 
    			   recv(sd, &recv_data, sizeof(recv_data), 0);
    			   printf("%s\n", recv_data); 
    			   break;
    
    		case 'C' : printf("\nChecking balance...");
    				   send(sd, &my_data, sizeof(my_data), 0);
    				   recv(sd, &recv_data_int, sizeof(recv_data_int), 0);
    				   printf("\nYour balance is ");
    			           printf("%d Pounds\n", recv_data_int);		 
    				   break;
    			 
    		case 'M' : printf("\nReceiving mini statement..."); 
    				   
    				   send(sd, &my_data,sizeof(my_data),0);
    				   recv(sd, &recv_mini,sizeof(&recv_mini) , 0);
    				     //struct store recv_mini[sizeof(&recv_mini)];
    				 
    				   
    				for (i=0; i < sizeof(&recv_mini); i++)
    				   {
    					printf("%c", recv_mini[i].data_char);
    					printf("%d", recv_mini[i].data_int);
    				   }
    				   break;
    
    		case 'Q' :printf("\nQuitting...\n"); 
    			  break;
    
    			default	 : printf("\nERROR you have not entered a valid letter, please start over");
    			 break;
    	}
    	
    
    
    
    
    
    return 0;
    	  
    }

    Sorry about all the code! Also thanks very much for all of your help thus far.

  10. #10
    Just kidding.... fnoyan's Avatar
    Join Date
    Jun 2003
    Location
    Still in the egg
    Posts
    275
    hi

    i did not look your last message (too long to be read in midnight!). So, for your previous message...

    Try to use fork() your application and each child would reply one request from another client. Or, you can use threads...

    And two more things...You must get a warning while compiling your code that is about main, there is no return statement! And always make error checking in networking functions. Most of them return -1 on error.

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Moved to network forum.
    It would be a good idea if you worked your way through some of the sticky threads at the top of this forum.

  12. #12
    Registered User
    Join Date
    Dec 2005
    Posts
    29
    would it be possible for this thread to be deleted? Or at least allow me to remove some of my code...

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Sure, you can edit out all your posts if you want, but if the result is a meaningless thread then it will most likely be deleted for good.
    It's not a good idea to make a habit of it though.

  14. #14
    Registered User
    Join Date
    Dec 2005
    Posts
    29
    I won't make a habit of it, as I realise it is completely pointless...the only reason I ask is that I've put alot of code up, and I don't want others to get an easy ride but simply copying what I have put...

    I can't seem to edit anything before 16/12/05.....tis why I asked really....

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. RE: client/server shared memory problem
    By hampycalc in forum C Programming
    Replies: 0
    Last Post: 03-10-2006, 02:26 PM
  2. Client/server won't connect
    By Lateralus in forum Networking/Device Communication
    Replies: 0
    Last Post: 06-15-2005, 07:48 AM
  3. Client/Server and Multithreading
    By osal in forum Windows Programming
    Replies: 2
    Last Post: 07-17-2004, 03:53 AM
  4. client/server program
    By purple in forum C Programming
    Replies: 3
    Last Post: 11-01-2002, 08:52 PM
  5. Client/Server Programming!!!
    By Silverdream in forum C Programming
    Replies: 4
    Last Post: 03-30-2002, 12:19 AM