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 */
}