[Ironruby-core] Patch submission - sockets

John Messerly jomes at microsoft.com
Sun Jan 6 00:51:03 EST 2008

Terence Lewis:

> Please find attached the beginnings of a sockets implementation for
> IronRuby. Included in this patch is the following:
> - Class BasicSocket
> - Class IPSocket
> - Class TCPSocket
> - Class TCPServer

Thanks for the patch. I'm checking it in now; it'll be included in the next SVN update.

> These classes aren't completely fleshed out, but they are functional
> to the point where I could create a very primitive web server using
> TCPServer that returns a dynamic HTML page which displays the current
> time, and read that page using either TCPSocket or my web browser.

I created a very simple manual test written in Ruby (will be under tests/libraries/socket/manual_socket.rb). It's really basic, hopefully we can expand it into an better test.

(although, it was pretty cool seeing IronRuby serve up a web page :) )

> A couple of points:
>  <snip>
> 2)      This is my first contribution to an open source project, and
> I'm
> under no illusions as to the many flaws in this code. Any comments,
> criticism or suggestion is welcome, and I assume that the code will be
> reviewed before being accepted.

Overall, it looks great. I made some small changes before checking in. Basically:

1. Added a method to convert AddressFamily values into strings (you're right, it doesn't appear System.Net has anything like that)

2. Added Protocols.CastToString in a few places & improved conversions. Protocol handling in Ruby is tricky--I usually test methods out in MRI and see what conversion methods they call if passed an arbitrary object. to_str & to_int being the common ones. I think we have a Protocol method for most of the MRI conversions now, so typically you should just need to call one of them.

3. TCPSocket#open needed a different implementation. This is a thing to watch out for in singleton methods--do they return an instance of the derived type, if you call them from a derived class? For example, if you do "class MyTCPSocket < TCPSocket; end" then MyTCPSocket.open, you actually get back an instance of MyTCPSocket. The way to do this in our system is to create a dynamic site that calls "new". Also, TCPSocket#open needed to yield to the block. I added that, which had the nice side effect of removing the need for TCPServer#open.

4. For TCPServer#new, we support optional parameters in the middle of the argument list, so I changed the code to use that. Also changed it to just take two args. Usually you don't need a params array unless the method takes an arbitrary number of args.

5. I added some to/from byte array helpers to MutableString to make those conversions easier. (Should get even easier once we convert to a byte-array based string like Ruby uses)

> 3)      There are no automated tests with this code :(. I'm more than
> happy
> to write tests, but I need some help and guidance about what tests to
> write (or use if there are existing tests for this functionality in
> JRuby or Rubinius). It seems to me that testing sockets is quite hard,
> because of the need to make sure the tests run on different machines
> and networks.

Yeah, I couldn't find any Rubinius tests for socket. JRuby might have some, I'll need to check.

> Thanks for your time


- John

More information about the Ironruby-core mailing list