• Welcome to Valhalla Legends Archive.
 

weird select() problem on FreeBSD

Started by nslay, June 16, 2005, 01:19 AM

Previous topic - Next topic

nslay

While pondering FreeBSD socket programming I created a simple program that connects to battle.net, logs in, and spits out everything bnet sends.
I originally wanted to use select so I could read the keyboard and the socket at the same time (none of that "fancy" MS socket stuff is on Unix of course)
I don't have the code in front of me, but I basically did this

Assume the connection was already established and 0x03 was sent
Quote
fd_set reads;
FD_ZERO(&reads);
FD_SET( sock, &reads );

while( select( 1, &reads, 0, 0, 0 ) > 0 ) {
//Do some cool stuffs here :o  ... but not really because it doesn't work!  >:(
}

now, of course I used select as a loop condition, when positive continue looping, else die!  This is just an example.  Now, I am aware I put a null pointer for the time parameter, I want it to be indefinate blocking ... however, it should return 1 when the socket recieves data even though it is indefinate blocking   :'(

Again, select appears to screw up since recv does the job just fine.
Now, either select is fudged or sockets aren't fds (which I am pretty sure they are)


OnlyMeat

Shouldn't the first parameter for select be the actual socket returned from a socket() call?. You shouldn't be using a fixed value of 1 surely.

You could try doing something like this:


select(sock, &rread, (fd_set *)0, (fd_set *)0, &to);


to is a struct timeval;

nslay

Quote from: OnlyMeat on June 16, 2005, 03:58 AM
Shouldn't the first parameter for select be the actual socket returned from a socket() call?. You shouldn't be using a fixed value of 1 surely.

You could try doing something like this:


select(sock, &rread, (fd_set *)0, (fd_set *)0, &to);


to is a struct timeval;

http://www.freebsd.org/cgi/man.cgi?query=select&apropos=0&sektion=0&manpath=FreeBSD+5.4-RELEASE&format=html
no, you stick the socket inside of a fd_sets variable, the first parameter is the number of file descriptors to check... in this case 1


NicoQwertyu

#4
Quote
ERRORS
     An error return from select() indicates:

     [EBADF]One of the descriptor sets specified an invalid
descriptor.

     [EFAULT]One of the arguments readfds, writefds, exceptfds, or
timeout points to an invalid address.

     [EINTR]A signal was delivered before the time limit expired
and before any of the selected events occurred.

     [EINVAL]The specified time limit is invalid.  One of its com-
ponents is negative or too large.

     [EINVAL]The nfds argument was invalid.

Perhaps try changing your while loop to check for errors as well.  Maybe something else is going on.

Edit: Nevermind.  Re-read your post and saw that it's blocking indefinently.

nslay

Quote from: OnlyMeat on June 16, 2005, 03:58 AM
Shouldn't the first parameter for select be the actual socket returned from a socket() call?. You shouldn't be using a fixed value of 1 surely.

You could try doing something like this:


select(sock, &rread, (fd_set *)0, (fd_set *)0, &to);


to is a struct timeval;

This is slightly correct actually.  It turns out that fd_sets are just bitfields and when FD_SET is used, it just switches that bit on at the fd's value.  When I ran it, the socket returned was 3, this turned on the 4th bit in the field so in order for select to work, the first parameter would have to be 4 since it checks the first 0 - n-1 bits in the field.


nslay

Quote from: NicoQwertyu on June 16, 2005, 08:10 PM
Aha! I prevail!

Quote
... the first parameter had to be the highest descriptor in the set + 1.

Moo :o