[Ironruby-core] IO#read for socket (SocketStream.cs)

はしもとけんいち ken1hasimoto at gmail.com
Tue Nov 17 00:23:24 EST 2009


Thank you for filing my report.

I forgot to attach my test scripts.(Sorry, it is NOT rubyspec.)
I attach two test case that was used in my investigation work.

1. druby test case.

  How to execute
    First  c:\> ir.exe server.rb
    Second c:\> ir.exe client_2.rb

  client_2.rb does NOT raise Exception in matz ruby.

2. TCPServer/TCPSocket test case.

  How to execute
    First  c:\> ir.exe s.rb
    Second c:\> ir.exe c.rb

  c.rb does NOT display "false" line to console in matz ruby.

NOTE:
I think that '0x0a' char cause the problem of my report.
Because, if buffer does NOT contain the '0x0a' char, my socket program
is success.
I guess that below:
1st:The writer program send a buffer (that contained the '0x0a' char)
to write socket stream, it do flush stream every '0x0a' char.
Next:The write socket stream send out a packet (that is splited by
'0x0a' char) to a Network stack.
Thus:The packet is fragmented, and the reader program receives  a
packet smaller than sent buffer.
     (Of course, the reader program can receive a remain data in the
next API call.)

Thank you.
B.R. Kenichi HASHIMOTO

2009/11/17 Tomas Matousek <Tomas.Matousek at microsoft.com>:
> I've filed a bug http://ironruby.codeplex.com/WorkItem/View.aspx?WorkItemId=3122.
>
> Thanks for the report and fix,
> Tomas
>
> -----Original Message-----
> From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of ????????
> Sent: Monday, November 16, 2009 12:45 AM
> To: Ironruby-core
> Subject: [Ironruby-core] IO#read for socket (SocketStream.cs)
>
> Hello, I'm kenichi hashimoto.
> I'm Japanese. I don't write english well.
>
> -------------
> I modified the IronRuby Libirary for reading from the socket to run the script of the druby-library.
> The druby library is contained the standard ruby library.
>
> [BACKGROUND]
> I wrote two scripts that use the druby, and I tested it.
> I saw a exception of the druby when a client script requested to the server script ( I wrote both the client and the server ) on the IronRuby 0.9.2.
> This exception means that 'the druby library read the datum from the socket, but size is corrputed'.
> Of course, this scripts is not occurred the exception in Matz Ruby
> 1.8.7 and 1.9.1.
>
> [CAUSE]
> I confirm that protocol of the druby and communication seq, I found the error that when the druby requests to read the socket with a size, sometimes the read methods return a data smaller than specify the read method.
> The Ruby IO#Read( size ) MUST recive the buffer required size. If buffer is reached the request size, IO#read must block.
>
>
> [INVESTIGATION]
> I found the mistake in the
> \ironruby\Merlin\Main\Languages\Ruby\Libraries.LCA_RESTRICTED\Socket\SocketStream.cs
> .
> "_socket.Receive" does NOT block to reach the request size.
>
>        public override int Read(byte[] buffer, int offset, int count) {
>            int bytesToRead = _peeked ? count - 1 : count;
>            byte[] readBuffer = new byte[bytesToRead];
>            long oldPos = _pos;
>
>            if (bytesToRead > 0) {
>                int bytesRead = _socket.Receive(readBuffer, bytesToRead, SocketFlags.None);
>                _pos += bytesRead;
>            }
>
> I rewrote bellow:
>
>            int updatedOffset = 0;
>            while (bytesToRead > 0)
>            {
>                int bytesRead = 0;
>                if (bytesToRead > 0)
>                {
>                    bytesRead = _socket.Receive(readBuffer, bytesToRead, SocketFlags.None);
>                    _pos += bytesRead;
>                    bytesToRead -= bytesRead;
>                }
>
>                if (_peeked)
>                {
>                    // Put the byte we've already peeked at the beginning of the buffer
>                    buffer[offset] = _lastByteRead;
>                    // Put the rest of the data afterwards
>                    Array.Copy(readBuffer, 0, buffer, offset + 1 + updatedOffset, bytesRead);
>                    _pos += 1;
>                    _peeked = false;
>                }
>                else
>                {
>                    Array.Copy(readBuffer, 0, buffer, offset + updatedOffset, bytesRead);
>                }
>                updatedOffset += bytesRead;
>            }
>
>  Note:
>    This code assumes the 'count > 0'.
>    And I didn't consider about efficiency of the code.
>
> If my consider is correct, Please modify this problem.
>
> Thank you
> B.R. Kenichi HASHIMOTO.
> _______________________________________________
> Ironruby-core mailing list
> Ironruby-core at rubyforge.org
> http://rubyforge.org/mailman/listinfo/ironruby-core
>
> _______________________________________________
> Ironruby-core mailing list
> Ironruby-core at rubyforge.org
> http://rubyforge.org/mailman/listinfo/ironruby-core
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test_script.zip
Type: application/zip
Size: 1991 bytes
Desc: not available
URL: <http://rubyforge.org/pipermail/ironruby-core/attachments/20091117/ac93cc83/attachment-0001.zip>


More information about the Ironruby-core mailing list