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.
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
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>
Kevin Radcliffe
2009-Nov-17 06:08 UTC
[Ironruby-core] IO#read for socket (SocketStream.cs)
Hashimoto-san, Thanks I''ve attached your tests scripts and script explanation to the codeplex issue here: http://ironruby.codeplex.com/WorkItem/View.aspx?WorkItemId=3122 Best Regards, Kevin Radcliffe 2009/11/16 ???????? <ken1hasimoto at gmail.com>> 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 > > > > _______________________________________________ > Ironruby-core mailing list > Ironruby-core at rubyforge.org > http://rubyforge.org/mailman/listinfo/ironruby-core > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/ironruby-core/attachments/20091116/c5893c64/attachment.html>