Need select() fds_write and fds_exception tutorial

Started by
8 comments, last by pakloong82 17 years, 9 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
:)
Advertisement
They work the same as the read fd_set. Do you have a more specific question?
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
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
Quote:Original post by cmptrgear
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.
*** Source Snippet Removed ***

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).


The code not working... write and expection in select() not invoked.....



The code not woking, can't get select() to throw write and exception file descriptor......

Thanks


:)

This topic is closed to new replies.

Advertisement