Thread: I can't Storing data to use later

  1. #1
    Registered User errigour's Avatar
    Join Date
    Mar 2009
    Posts
    102

    I can't Storing data to use later

    I am trying to store data for my server but I can't seem to actually accomplish
    my task. I can't print variables of the structure with printf and the for loop doesn't
    execute at all. What am I doing wrong?

    Code:
    struct descr descr_list = NULL;
    
    int initialize_descr(int newfd, struct descr *p)
    {
    	struct descr *d;
    	d = descr_list;
    
    	if( d != 0)
    	{
    		while(d->next != 0)
    			d = d->next;
    		if(!(d->next = malloc(sizeof(struct descr))))
    			nonfatal("malloc failure initializing descr");
    		d = d->next;
    	}
    	else
    		if(!(d = malloc(sizeof(struct descr))))
    			nonfatal("malloc failure initializing descr");
    	d->newfd = newfd;
    	d->state = 1;p = d;
    }
    initialize_descr(newfd, d);
    printf("New connection: on socket:  %d,\r\n", d->newfd);
    for (d = descr_list; d; d = d->next)
    	if(FD_ISSET(d->newfd, &read_fds))
    		if (d->state == 1)
    			character_login(d);

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    It does help if you show actual code, not some "summary" that means something different.

    The last statement "p = d;" inside initialize_descr() does not change the value of p when the function returns.
    Code:
    int initialize_descr(int newfd, struct descr *p)
    { 
         /*  The rest of the stuff */
         p = d;
    }
    
    int main()
    {
        struct descr *d = NULL;   /*  initialise to something */
        
        initialize_descr(newfd, d);
    
        /*   d was passed by value to initialize_descr  so is still NULL here */
    }
    If you want initialize_descr() to be able to change d in main(), change it so the second argument is a pointer to pointer, and adjust accordingly.
    Last edited by grumpy; 08-16-2011 at 04:10 AM. Reason: Fixed typo in example
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #3
    Registered User errigour's Avatar
    Join Date
    Mar 2009
    Posts
    102
    do you want me to post the whole main.c? It's not very much.
    Last edited by errigour; 08-16-2011 at 04:06 AM. Reason: I sound like an idiot

  4. #4
    Registered User errigour's Avatar
    Join Date
    Mar 2009
    Posts
    102
    Also could you show me an example that will work? I'm not very good with pointers.

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    I'm not going to fix your code. That's your challenge.

    However, if you work out why the comments in the following code are true, you will be able to fix your problem yourself.
    Code:
    void fun1(SomeType *x)
    {
        x = NULL;
    }
    
    void fun2(SomeType **x)   /*  note two asterixes  */
    {
         *x = NULL;
    }
    
    int main()
    {
         SomeType y;
         SomeType *x = &y;
    
         fun1(x);     
           /*  x will still contain the address of y here.  It has not been changed by fun1() */
    
        fun2(&x);
    
           /*   x will now be the NULL pointer because fun2() has changed it */
    }
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  6. #6
    Registered User errigour's Avatar
    Join Date
    Mar 2009
    Posts
    102
    Will function one change any aspect of x?

  7. #7
    Registered User errigour's Avatar
    Join Date
    Mar 2009
    Posts
    102
    Also in function two you point to NULL but what would it look like if you
    wanted to change the address by pointing to a pointer? should it be
    *p = d; or *p = *d;

  8. #8
    Registered User errigour's Avatar
    Join Date
    Mar 2009
    Posts
    102
    I wanna guess *p=d;

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If you think about what "d" and "*d" mean, then you won't have to guess.

  10. #10
    Registered User errigour's Avatar
    Join Date
    Mar 2009
    Posts
    102
    I'm still having problem with the for loop. It doesn't seem to recognize any of the
    structures that I create. The entire code is below that.

    Code:
    	for (d = descr_list; d; d = d->next)
    		if(FD_ISSET(d->newfd, &read_fds))
    			if (d->state == 1)
    				character_login(d);
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <string.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include "math.h"
    #include "server.h"
    
    struct descr *descr_list = NULL;
    unsigned long long heart_pulse = 0;
    
    struct descr
    {
    	int newfd;                /* Send and receive from newfd */
    	short int state;          /* State of player in the game */
    	struct descr *next;       /* For generating a list */
    	struct input_queue *queue;/* Character input queue */
    };
    
    int initialize_descr(int newfd, struct descr **p)
    {
    	struct descr *d;
    	d = descr_list;
    
    	if( d != 0)
    	{
    		while(d->next != 0)
    			d = d->next;
    		if(!(d->next = malloc(sizeof(struct descr))))
    			nonfatal("malloc failure initializing descr");
    		d = d->next;
    	}
    	else
    		if(!(d = malloc(sizeof(struct descr))))
    			nonfatal("malloc failure initializing descr");
    	d->newfd = newfd;
    	d->state = 1;
    	if(!(d->queue = malloc(sizeof(struct descr))))
    		nonfatal("malloc failure initializing descr queue");
    	*p = d;
    }
    
    struct input_queue 
    { 
    	char ch_input[7024];	  /* Character input in queue */
    	struct input_queue *next; /* Queued input or null     */
    };
    
    char character_login(struct descr *d)
    {
    	int rbytes = 0;
    	const char er[] = "Character name is to large.\r\n\r\n";
    	const char ln[] = "\r\nCharacter name or (n)ew: ";
    	if ((rbytes = recv(d->newfd, d->queue->ch_input, 12, 0)) <= 0)
    	{
    	    if (rbytes == 0)
    		    printf("Socket %d hung up\n", d->newfd);
    		else
    		    nonfatal("Receiving a file descriptor");
    		d->state = 0;
    	}
    	
    	if (rbytes > 11)
    	{
    		send(d->newfd, er, sizeof er, 0);
    		send(d->newfd, ln, sizeof ln, 0);
    	}
    	else
    		d->state = 2;
    }
    
    int main()
    {	
    	struct sockaddr_in serv;
    	struct sockaddr_in inco;
    	struct timeval seconds;
    	socklen_t inclen;
    	int simpleSocket;
    	int clientSocket;
    	int yes = 1;
    	int fdmax;        // maximum file descriptor number
    	int newfd;
    
    	fd_set master;    // master file descriptor list
    	fd_set read_fds;  // will be watched to see if characters become available for reading
    	fd_set write_fds;  // will be watched to see if a write will not block
    	fd_set except_fds; // will be watched for exceptions.
    
    	seconds.tv_sec  = 0;      /* seconds for select to wait for connections     */
    	seconds.tv_usec = 1000;   /* microseconds for select to wait for connections
    	                           * there are 1,000 microseconds in a millisecond
    				               * there are 1,000 milliseconds in a second     
    				               * thus there are 1,000,000 Microseconds in one 
    				               * second, and there are 60 seconds in one minute */
    
    	printf("Process id #%i\n", getpid());
    	FD_ZERO(&master);    // clear the master and temp sets
    	FD_ZERO(&read_fds);
    	FD_ZERO(&write_fds);
    	FD_ZERO(&except_fds);
    
    	if ((simpleSocket=socket(AF_INET, SOCK_STREAM,0)) == -1)
    	{
    		fatal("Creating simpleSocket, AF_INET SOCK_STREAM failed");
    	}
    	fcntl(simpleSocket, F_SETFL, O_NONBLOCK); 
    	setsockopt(simpleSocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
      /*struct sockaddr_in
    	{
    		short   sin_family; /* must be AF_INET
    		u_short sin_port;
    		struct  in_addr sin_addr;
    		char    sin_zero[8]; /* Not used, must be zero
    	};
    	struct in_addr { int s_addr; }; */
    	serv.sin_family = AF_INET;
    	serv.sin_addr.s_addr = INADDR_ANY;
    	serv.sin_port = htons(2000);
    
    	if (bind(simpleSocket,(struct sockaddr *)&serv,sizeof(serv)) == -1)
    	{
    		close(simpleSocket);
    		fatal("Binding simpleSocket, AF_INET SOCK_STREAM failed");
    	}
    
    	if (listen(simpleSocket, 1000) == -1) 
    	{
    		close(simpleSocket);
    		fatal("Listening to simpleSocket, AF_INET SOCK_STREAM failed");
        }
    
    	// add the listener to the master set
        FD_SET(simpleSocket, &master);
    
        // keep track of the biggest file descriptor
        fdmax = simpleSocket; // so far, it's this one
    
    	for(;;)
    	{
    		struct descr *d;
    		
    		read_fds = master;
    		write_fds = master;
    		except_fds = master;
    
    		if (select(fdmax+1, &read_fds, &write_fds, &except_fds, &seconds) == -1)
                nonfatal("Select failed");
    		if (FD_ISSET(simpleSocket, &read_fds))
    		{
    			/* handle new connections */
    			newfd = accept(simpleSocket, (struct sockaddr *)&inco, &inclen);
    			if(newfd == -1)
    				nonfatal("Accepting a file descriptor");
    			else 
    			{
    				struct descr *init = NULL;
    				
    				FD_SET(newfd, &master); /* add to master set */
    				if (newfd > fdmax)      /* keep track of the max */
                      	fdmax = newfd;
        			const char name_prompt[] = "Character name or (n)ew: ";
        			send(newfd, name_prompt, sizeof name_prompt, 0);
    				initialize_descr(newfd, &init);
    				printf("New connection: on socket:  %d,\r\n", init->newfd);
    				printf("                sin_addr:   %s\r\n", inet_ntoa(inco.sin_addr));
    				/*
    				printf("			    sin_family: %s\n", inco.sin_family);
    				printf("			    sin_port:   %s\n", inco.sin_port);
    				printf("			    s_addr:     %s\n", inco.sin_addr.s_addr);
    				printf("                sin_zero:   %s\n", inco.sin_zero[8]);*/
    			}
    		} /* END FD_ISSET(simpleSocket, &read_fds) */
    		
    		for (d = descr_list; d; d = d->next)
    			if(FD_ISSET(d->newfd, &read_fds))
    				if (d->state == 1)
    					character_login(d);
    
    		heart_pulse++;
    		if (heart_pulse == 100000000) /* Longest int type unsigned long long int 18446744073709551616 */
    		{
    			int j;
    			const char tick[] = "tick.";
    			for(j = 0; j <= fdmax; j++) 
    			{
    				/* send to everyone! */
    				if (FD_ISSET(j, &master)) 
    				{
    					send(j, tick, sizeof tick, 0);
    				}
    			}
    			heart_pulse = 0;
    		}
    	}/* END for(;;).*/
        close(simpleSocket);
        exit(EXIT_SUCCESS);
    }
    Last edited by errigour; 08-16-2011 at 06:23 AM.

  11. #11
    Registered User errigour's Avatar
    Join Date
    Mar 2009
    Posts
    102
    thank you for your help.
    Last edited by errigour; 08-16-2011 at 06:05 AM. Reason: miss spelling

  12. #12
    Registered User errigour's Avatar
    Join Date
    Mar 2009
    Posts
    102
    Ok the tick message works now.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Data structure for storing serial port data in firmware
    By james457 in forum C Programming
    Replies: 4
    Last Post: 06-15-2009, 09:28 AM
  2. Replies: 3
    Last Post: 02-26-2008, 02:12 PM
  3. storing data
    By wart101 in forum C++ Programming
    Replies: 4
    Last Post: 01-03-2007, 01:08 AM
  4. Storing data in ORACLE or SQL
    By Arafat_211184 in forum C++ Programming
    Replies: 3
    Last Post: 05-03-2006, 01:14 AM
  5. storing data
    By CodeMonkey in forum C++ Programming
    Replies: 10
    Last Post: 01-19-2003, 10:29 PM