Setting a UDP socket to nonblocking

BlitzMax Forums/BlitzMax Programming/Setting a UDP socket to nonblocking

Chroma(Posted 2010) [#1]
I looked up how to set a UDP socket to nonblocking. I'm messing about in the socket.bmx file and put in an option for the CreateUDPSocket(nonblocking=False) command. The command in C to set the socket to nonblocking is "ioctlsocket".

I see this in Mark's code:
Private

Extern "os"
?Win32
Const FIONREAD=$4004667F
Function ioctl_( socket,opt,buf:Byte Ptr )="ioctlsocket@12"
?MacOS
Const FIONREAD=$4004667F
Function ioctl_( socket,opt,buf:Byte Ptr )="ioctl"
?Linux
Const FIONREAD=$541b
Function ioctl_( socket,opt,buf:Byte Ptr )="ioctl"
?
End Extern


Now here's the code to set a UDP socket to nonblocking:
#if PLATFORM == PLATFORM_MAC || PLATFORM == PLATFORM_UNIX

        int nonBlocking = 1;
        if ( fcntl( handle, F_SETFL, O_NONBLOCK, nonBlocking ) == -1 )
        {
            printf( "failed to set non-blocking socket\n" );
            return false;
        }

    #elif PLATFORM == PLATFORM_WINDOWS

        DWORD nonBlocking = 1;
        if ( ioctlsocket( handle, FIONBIO, &nonBlocking ) != 0 )
        {
            printf( "failed to set non-blocking socket\n" );
            return false;
        }

    #endif


Can I get just a tad bit of help with this please.


Chroma(Posted 2010) [#2]
Interesting read here: http://msdn.microsoft.com/en-us/library/ms738573(VS.85).aspx

I see this line in socket.bmx:
Const FIONREAD=$4004667F

How would I find the value I would need to set FIONBIO to? and how did Mark know to set FIONREAD to $4004667F?


Chroma(Posted 2010) [#3]
Anyone? Buehller?

EDIT: Stuff like this is was makes BMax unbearably frustrating at times. I know it's simple to do...and I wish the option had been put in from the get go. It's only a line or two. I just don't know what value to put in for FIONBIO.

Going to bed...hopefully someone can shed some light on this.


Chroma(Posted 2010) [#4]
So no one has a clue?


skidracer(Posted 2010) [#5]
Read blocking or write blocking?

To avoid read blocking always check available bytes before you read and it will never block.

I'd like to see some code that causes write to block b4 I could comment. Expecting network issues to "just be simple" rather than a wall 4000 high of canned worms I think is also a mistake.


Chroma(Posted 2010) [#6]
I'm wanting to set it so when you try to read from it if there's no data it will keep going. But I know what you're going to say (if readavail >0) etc... Please read below. I'm just trying to change the UDP socket to nonblocking via the ioctl command.

By default sockets are set in what is called “blocking mode”. This means that if you try to read a packet using “recvfrom”, the function will not return until a packet is available to read. This is not at all suitable for our purposes. Video games are realtime programs that simulate at 30 or 60 frames per second, they can’t just sit there waiting for a packet to arrive!

The solution is to flip your sockets into “non-blocking mode” after you create them. Once this is done, the “recvfrom” function returns immediately when no packets are available to read, with a return value indicating that you should try to read packets again later.

To avoid read blocking always check available bytes before you read and it will never block.
Yep I'm already doing that. So you're saying I don't have to worry about setting it to nonblocking?


skidracer(Posted 2010) [#7]
If you have no definite UDP problem, I don't see how I can help with a solution.

Datagrams are not streams and shouldn't IMHO be encapsulated as such.


Chroma(Posted 2010) [#8]
Ah so you're saying that in the way we utilize ReadAvail, we don't have to set the UDP socket to nonblocking because we don't actually try to do a recvfrom until we know there's something to read. Makes sense.

So there's no reason to set UDP sockets to nonblocking in BMax people. Move along, nothing to see here.