Hi,

 It's possible to have asynchronous socket programming just with select()
and without fork()ing !?

 Asynchronous server it's a server which handle and response to several
requests at the same time, rigth !?
 I'm trying to do that. ;)

 On attachment, server.c file, as it's at the moment, is only using
select() but if I make a connect #1 and then connect #2 without
disconnect #1 i'm not able to do anything on #2 until #1 get closed!

 If I uncomment the lines that had fork()ing process it already support
asynchronous communications ! It's a good appologie(use select+fork) or
should I only work with fork()ing processes !?

 There's on file a string comparations(strcmp) which is never executed! It
seems read() write to buffer's variable more than the expected words - for
"nemanuel" i got a strlen of 10 !!


 Thanks for your pacience.

 Best regards,
   Nuno Carvalho 
 
จจจจจจจจจจจจจจจจจจจจจจจจจจจจจจ
   Nuno Emanuel F. Carvalho
 Dep. Informatics Engineering
    University of Coimbra

  PGP key available at finger
จจจจจจจจจจจจจจจจจจจจจจจจจจจจจจ
#include <stdio.h>		/* Basic I/O routines 		*/
#include <sys/types.h>		/* standard system types 	*/
#include <sys/wait.h>
#include <netinet/in.h>		/* Internet address structures 	*/
#include <sys/socket.h>		/* socket interface functions 	*/
#include <netdb.h>		/* host to IP resolution 	*/
#include <sys/time.h>		/* for timeout values 		*/
#include <unistd.h>		/* for table size calculations 	*/

#define	PORT		5060	/* port of our echo server */
#define	BUFLEN		1024	/* buffer length 	   */

void main()
{
    int			fd;		/* index counter for loop operations */
    int			result; 		/* system calls return value storage */
    int			socket_fd; 		/* socket descriptor */
    int			client_fd; 		/* new connection's socket descriptor */
    char		buf[BUFLEN+1];  /* buffer for incoming data */
    struct sockaddr_in	saddress; 		/* Internet address struct */
    struct sockaddr_in	sclient_address; 		/* client's address struct */
    int         	size_cliente_address; 	/* size of client's address struct */
    fd_set		descritores; 		/* set of open sockets */
    fd_set		dleitura, descrita; 		/* set of sockets waiting to be read */
    int			size_table_fd; 		/* size of file descriptors table */
    
    int pid ;

    /* initiate machine's Internet address structure */
    /* first clear out the struct, to avoid garbage  */
    memset(&saddress, 0, sizeof(saddress));
    /* Using Internet address family */
    saddress.sin_family = AF_INET;
    /* copy port number in network byte order */
    saddress.sin_port = htons(PORT);
    /* we will accept cnnections coming through any IP	*/
    /* address that belongs to our host, using the	*/
    /* INADDR_ANY wild-card.				*/
    saddress.sin_addr.s_addr = INADDR_ANY;

    /* allocate a free socket                 */
    /* Internet address family, Stream socket */
    socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_fd < 0) {
	perror("socket: allocation failed");
    }

    /* bind the socket to the newly formed address */
    result = bind(socket_fd, (struct sockaddr *)&saddress, sizeof(saddress));

    /* check there was no error */
    if (result) {
	perror("bind");
    }

    /* ask the system to listen for incoming connections	*/
    /* to the address we just bound. specify that up to		*/
    /* 5 pending connection requests will be queued by the	*/
    /* system, if we are not directly awaiting them using	*/
    /* the accept() system call, when they arrive.		*/
    result = listen(socket_fd, 5);

    /* check there was no error */
    if (result) {
	perror("listen");
    }

    /* remember size for later usage */
    size_cliente_address = sizeof(sclient_address);

    /* calculate size of file descriptors table */
    size_table_fd = getdtablesize();

    /* close all file descriptors, except our communication socket	*/
    /* this is done to avoid blocking on tty operations and such.	*/
    for (fd=0; fd<size_table_fd; fd++)
	if (fd != socket_fd)
	    close(fd);

    /* we innitialy have only one socket open,	*/
    /* to receive new incoming connections.	*/
    FD_ZERO(&descritores);
    FD_SET(socket_fd, &descritores);
    /* enter an accept-write-close infinite loop */
    while (1) {
	/* the select() system call waits until any of	*/
	/* the file descriptors specified in the read,	*/
	/* write and exception sets given to it, is	*/
	/* ready to give data, send data, or is in an 	*/
	/* exceptional state, in respect. the call will	*/
	/* wait for a given time before returning. in	*/
	/* this case, the value is NULL, so it will	*/
	/* not timeout. dsize specifies the size of the	*/
	/* file descriptor table.			*/
	dleitura = descritores ;
    descrita = descritores ;
	result = select(size_table_fd, &dleitura, &descrita, NULL, (struct timeval *)NULL);

	/* if the 's' socket is ready for reading, it	*/
	/* means that a new connection request arrived.	*/
	if (FD_ISSET(socket_fd, &dleitura)) {
	    /* accept the incoming connection */
       	    client_fd = accept(socket_fd, (struct sockaddr *)&sclient_address, &size_cliente_address);

       	    /* check for errors. if any, ignore new connection */
       	    if (client_fd < 0)
       		continue;

	    /* add the new socket to the set of open sockets */
	    FD_SET(client_fd, &descritores);

	    /* and loop again */
	    continue;
	}

	/* check which sockets are ready for reading,	*/
	/* and handle them with care.			*/
	for (fd=0; fd<size_table_fd; fd++)
    {
	    if (fd != socket_fd && (FD_ISSET(fd, &dleitura) || FD_ISSET(fd, &descrita)))    /* read from the socket */
        {

/* 
           if( (pid=fork())<0 )
           {
             perror("[FORK]");
             exit(0) ;
           }
           else if( pid==0 )
           {
             close(socket_fd);
*/             
             write(fd, "Username: ", strlen("Username: "));
             result = read(fd, buf, BUFLEN);
             buf[result]= '\0';
             if(strcmp(buf,"nemanuel")==0)
                printf("\nHELLO NUNO CARVALHO");
             printf("\n->%s<-", buf);
             
/*             
             exit(0);
           }
*/           
           FD_CLR(fd, &descritores);           
           close(fd);
           
        }
    }      /*  FOR */

    } /* WHILE */
}

Reply via email to