select system call usage doubt
i have a tcp concurrent server program as below.
my doubt is in the for loop , I have written my doubt near the for loop with in comments
If any body can share there knowledge it would give me complete understanding of the select call usage.
Code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#define SRV_TCP_PORT 8000
#define MAX_MSG 100
void errExit(char *str)
{
puts(str);
exit(0);
}
int main()
{
int srvSockFd,newSockFd,fd;
struct sockaddr_in srvAdr, cliAdr;
int cliLen,n;
fd_set readfds, testfds;
int stat;
char mesg[MAX_MSG];
if((srvSockFd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
errExit("Can't open datagram socket\n");
memset(&srvAdr, 0, sizeof(srvAdr));
srvAdr.sin_family = AF_INET;
srvAdr.sin_addr.s_addr = htonl(INADDR_ANY);
srvAdr.sin_port = htons(SRV_TCP_PORT);
if(bind(srvSockFd,(struct sockaddr*)&srvAdr, sizeof(srvAdr)) < 0)
errExit("Can't bind local address \n");
listen(srvSockFd,5);
FD_ZERO(&readfds);
FD_SET(srvSockFd,&readfds);
printf("Server waiting for new connection :\n");
while(1)
{
testfds = readfds;
stat = select(FD_SETSIZE, &testfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0);
if(stat < 1)
errExit("select error \n");
for(fd = 0; fd < FD_SETSIZE; fd++)
{
if(FD_ISSET(fd,&testfds))
{
/* here once any fd is ready it will come in to loop .
why do we need to compare is it srvSockFd or not ? */
if(fd == srvSockFd)
{
newSockFd = accept(fd, (struct sockaddr *)0, NULL);
FD_SET(newSockFd, &readfds);
/* why cant we directly use the testfd set it selft to set the newSockFD
why do we need the second fd set readfd here ?
here is readfds and testfds are reference based , i mean any change made to
readfds will take effect on testfds? */
printf("Adding client fd: %d to readFdSet \n",newSockFd);
}
else
{
/* This is my fundamental doubt like when will it come to else part
once fd is ready it will go the above block so when and how it comes to this
block */
n = recv(fd, mesg, MAX_MSG, 0);
if(n < 0)
errExit("recv error \n");
else if(n == 0)
{
close(fd);
FD_CLR(fd, &readfds);
printf("Removing client fd: %d from readFdSet \n",fd);
}
else
{
if(send(fd,mesg,n,0) != n)
errExit("send error \n");
}
}
}
}
}
}