# How to accept a varying amount of UDP packets using recvfrom

**URL:** <https://www.ruby-forum.com/t/how-to-accept-a-varying-amount-of-udp-packets-using-recvfrom/171755>\
**Category:** Ruby\
**Created:** [July 8, 2009, 6:10pm UTC](https://www.ruby-forum.com/t/how-to-accept-a-varying-amount-of-udp-packets-using-recvfrom/171755 "2009-07-08T18:10:07Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![owossoborn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/f19dbf/32.png) [@owossoborn](https://www.ruby-forum.com/u/owossoborn)\
**Post date:** [July 8, 2009, 6:10pm UTC](https://www.ruby-forum.com/t/how-to-accept-a-varying-amount-of-udp-packets-using-recvfrom/171755/1 "2009-07-08T18:10:07Z")

</div>

I’m currently creating an application that can query a game-server for  
its status, total players, hostname, etc. I send out a challenge packet,  
and in return I receive between 1 and 3 UDP packets.

Is there an effective way to deal with receiving a varying amount of UDP  
packets? If I do a recvfrom for two packets, the process will time out  
if only a single packet arrives.

Any assistance is appreciated!

---

<div class="post-metadata">

**Author:** ![owossoborn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/f19dbf/32.png) [@owossoborn](https://www.ruby-forum.com/u/owossoborn)\
**Post date:** [July 8, 2009, 6:36pm UTC](https://www.ruby-forum.com/t/how-to-accept-a-varying-amount-of-udp-packets-using-recvfrom/171755/2 "2009-07-08T18:36:07Z")

</div>

Randy G. wrote:

> I’m currently creating an application that can query a game-server for  
> its status, total players, hostname, etc. I send out a challenge packet,  
> and in return I receive between 1 and 3 UDP packets.
> 
> Is there an effective way to deal with receiving a varying amount of UDP  
> packets? If I do a recvfrom for two packets, the process will time out  
> if only a single packet arrives.
> 
> Any assistance is appreciated!

You need to specify how long to wait until you decide that no more  
packets will arrive. Can you guarantee that the packets will arrive  
within 500ms? Then make that your timeout.

You can timeout socket reads with Kernel#select(), but you probably knew  
that.

---

<div class="post-metadata">

**Author:** ![owossoborn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/f19dbf/32.png) [@owossoborn](https://www.ruby-forum.com/u/owossoborn)\
**Post date:** [July 8, 2009, 6:47pm UTC](https://www.ruby-forum.com/t/how-to-accept-a-varying-amount-of-udp-packets-using-recvfrom/171755/3 "2009-07-08T18:47:14Z")

</div>

From: “Randy G.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> I’m currently creating an application that can query a game-server for  
> its status, total players, hostname, etc. I send out a challenge packet,  
> and in return I receive between 1 and 3 UDP packets.
> 
> Is there an effective way to deal with receiving a varying amount of UDP  
> packets? If I do a recvfrom for two packets, the process will time out  
> if only a single packet arrives.

Generally, use select to specifiy the desired timeout.

However, it’s a little more complicated with ruby and UDP, such  
that one may end up needing to wrap the recvfrom in a  
timeout { } block anyway. (On some operating systems, if the  
UDP packet has a checksum error, select can return ready,  
but recvfrom will block. (And in many (all?) versions of ruby,  
setting fcntl O\_NONBLOCK does not help due to ruby’s  
internals.))

This rubyforge project has code for receiving one-or-more UDP  
packets from a Quake2 server:

[http://rubyforge.org/scm/?group\_id=288](http://rubyforge.org/scm/?group_id=288)

Unfortunately, it doesn’t seem possible to browse the CVS  
repository via the web anymore, but you can still check out the  
source via anonymous CVS as described on that page.

E.g.

cvs -d:pserver:removed\_email\_address@domain.invalid:/var/cvs/dorkbuster login  
cvs -z3 -d:pserver:removed\_email\_address@domain.invalid:/var/cvs/dorkbuster co  
dorkbuster

The relevant source file is: dorkbuster/dbcore/q2rcon.rb

Here’s the innermost receive method: [http://pastebin.com/f716b381d](http://pastebin.com/f716b381d)

Hope this helps,

Bill

---

<div class="post-metadata">

**Author:** ![owossoborn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/f19dbf/32.png) [@owossoborn](https://www.ruby-forum.com/u/owossoborn)\
**Post date:** [July 8, 2009, 7:12pm UTC](https://www.ruby-forum.com/t/how-to-accept-a-varying-amount-of-udp-packets-using-recvfrom/171755/4 "2009-07-08T19:12:42Z")

</div>

Bill K. wrote:

> Generally, use select to specifiy the desired timeout.
> 
> However, it’s a little more complicated with ruby and UDP, such  
> that one may end up needing to wrap the recvfrom in a  
> timeout { } block anyway. (On some operating systems, if the  
> UDP packet has a checksum error, select can return ready,  
> but recvfrom will block. (And in many (all?) versions of ruby,  
> setting fcntl O\_NONBLOCK does not help due to ruby’s  
> internals.))
> 
> This rubyforge project has code for receiving one-or-more UDP  
> packets from a Quake2 server:
> 
> [http://rubyforge.org/scm/?group\_id=288](http://rubyforge.org/scm/?group_id=288)
> 
> The relevant source file is: dorkbuster/dbcore/q2rcon.rb
> 
> Here’s the innermost receive method: [http://pastebin.com/f716b381d](http://pastebin.com/f716b381d)
> 
> Hope this helps,
> 
> Bill

Thanks for your replies!

The code in that pastie is a bit beyond my current skill level (just  
began programming a few days ago), but I’ll see if I can make some sense  
of it and incorporate it into my own app. Thanks for your help!
