Advertisement

Need select() fds_write and fds_exception tutorial

Started by June 22, 2006 10:37 AM
8 comments, last by pakloong82 18 years, 8 months ago
hi... can anyone provide some tutorial about how to utilize fds_write and fds_exception in selec()..... most of the tutorial that I had read only utilize fds_read, so I need tutorial on how to use fds_write and fds_exception in select()... Thanks
:)
They work the same as the read fd_set. Do you have a more specific question?
Advertisement
code:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#define PORT 9034   // port we're listening onint main(void){    fd_set master;   // master file descriptor list    fd_set read_fds; // temp file descriptor list for select()    fd_set write_fds;    fd_set except_fds;    struct sockaddr_in myaddr;     // server address    struct sockaddr_in remoteaddr; // client address    int fdmax;        // maximum file descriptor number    int listener;     // listening socket descriptor    int newfd;        // newly accept()ed socket descriptor    char buf[256];    // buffer for client data    int nbytes;    int yes=1;        // for setsockopt() SO_REUSEADDR, below    socklen_t addrlen;    int i, j;    FD_ZERO(&master);    // clear the master and temp sets    FD_ZERO(&read_fds);    FD_ZERO(&write_fds);    FD_ZERO(&except_fds);    // get the listener    if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) {        perror("socket");        exit(1);    }    // lose the pesky "address already in use" error message    if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes,                                                        sizeof(int)) == -1) {        perror("setsockopt");        exit(1);    }    // bind    myaddr.sin_family = AF_INET;    myaddr.sin_addr.s_addr = INADDR_ANY;    myaddr.sin_port = htons(PORT);    memset(&(myaddr.sin_zero), '\0', 8);        if (bind(listener, (struct sockaddr *)&myaddr, sizeof(myaddr)) == -1) {        perror("bind");        exit(1);    }    // listen    if (listen(listener, 10) == -1) {        perror("listen");        exit(1);    }       FD_SET(listener, &master);        fdmax = listener; // so far, it's this one    // main loop    for(;;) {        read_fds = master; // copy it        if (select(fdmax+1, NULL, &write_fds,&except_fds, NULL) == -1) {            //perror("select");            exit(1);        }        for(i = 0; i <= fdmax; i++)         {            if(FD_ISSET(i, &write_fds))            {            	printf("write\n");            	            }            if(FD_ISSET(i, &except_fds)            {                printf("Exception occur\n");            }        }    }        return 0;}


well the code i provide simply not working...... can't get it to invoke write and exception....

Thanks

[Edited by - pakloong82 on June 22, 2006 1:16:20 PM]
:)
Maybe I am missing something but you havent added any sockets to the write_fds or except_fds.
"Pfft, Facts! Facts can be used to prove anything!" -- Homer J. Simpson
for(;;) {        read_fds = master; // copy it                if (select(fdmax+1, &read_fds, &write_fds, NULL, NULL) == -1) {            perror("select");            exit(1);        }        if(FD_ISSET(listener, &write_fds))        {            	printf("write\n");            	        }        if(FD_ISSET(listener, &except_fds))        {               printf("Exception occur\n");        }        }  


ok... the code above should work?

Thanks
:)
If you want select to return when it is possible to write to a socket without blocking or if there is an exception on the socket you need to add that socket to the write_fds and except_fds before calling select.

I see what you are doing now.

//this is the important part, you need to add the listener//socket to these two sets.FD_SET(listener, &write_fds);FD_SET(listener, &except_fds);int count = 0;//select will return the number of ready socketscount = select(fdmax+1, 0, &write_fds, &except_fds, NULL);if(count == -1){   exit (1);}for(int i = 0; i < count; ++i){   if(FD_ISSET(listener, &write_fds);   {       //do write stuff here   }   if(FD_ISSET(listener, &except_fds);   {      //do exception stuff here   }}


The problem is you are not adding any sockets to the write_fds and except_fds, so select is never going to return anything related to them.
"Pfft, Facts! Facts can be used to prove anything!" -- Homer J. Simpson
Advertisement
well, the problem is how to invoke:

   if(FD_ISSET(listener, &write_fds))   {       //do write stuff here   }   if(FD_ISSET(listener, &except_fds))   {      //do exception stuff here   }


the 2 codition

1)if(FD_ISSET(listener, &write_fds))

2)if(FD_ISSET(listener, &except_fds))

how do we execute both of them?

cause I need to test the statement is working or not...

Thanks
:)
I think I see what you mean, you want to test the code by having select return based on those conditions?

If that is the case the write one is pretty easy.
Open a socket and write a large amount of data to it at once so it fills up the buffer, then call select. When the socket has room to send more data the select will return.

I think this should work, but I havent tested it out so there may be errors.
char * buffer = new char[8192]; //8kb of data//fill the buffer with some datafor(int i = 0; i < 8192; ++i)   buffer = i %256;FD_SET(write_socket, &write_fds);send(write_socket, buffer, sizeof(char)*8192, 0);//select should return when it is ok to write more data to write_socketselect (max_fd, 0, &write_fds, &except_fds, 0);...


I have never used the except_fds argument before so I am not sure when it will return. I assume it will return if there is some sort of error on the socket. You might try something like writing UDP data to a random port which should result in a Port unreachable message (I think it is Port unreachable).
"Pfft, Facts! Facts can be used to prove anything!" -- Homer J. Simpson
The code not woking, can't get select() to throw write and exception file descriptor......

Thanks


:)

This topic is closed to new replies.

Advertisement