[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Fwd: Possible bug with Socket write

hemant

4/8/2008 9:33:00 AM

Here is our sample server program:

#server code
require 'socket'

serv = TCPServer.new(2202)
if(sock = serv.accept)
p sock.read(4)
sock.close
end
serv.close

# client code
require "socket"

a = TCPSocket.open("localhost",2202)
b = a.write("Hello")
p b
sleep(10)
p a.closed?
b = a.write("hello") #line no 8
p b

write in client succeeds on line#8 silently, without raising an
exception and number of written bytes also seems correct even though
server socket is closed.

For next write Ruby will usually raise EPIPE, but it means that almost
ALWAYS you stand to loose one message. Now on #rubinius, Eric Hodel
mentioned that it could be intentional. But I fail to see how so?

PS: After getting no response on ruby-core for about 4 days, I am
bumping this thread on ruby-talk, hoping to see if its indeed a bug or
I am doing something wrong.

1 Answer

Lars Christensen

4/11/2008 12:34:00 PM

0

On Apr 8, 11:33 am, hemant <gethem...@gmail.com> wrote:
>  write in client succeeds on line#8 silently, without raising an
>  exception and number of written bytes also seems correct even though
>  server socket is closed.

I can't explain why Ruby or the socket API does not throw an error in
all cases. I have tested a bit with various combinations and there
appear to be factors that make the outcome appear somewhat random.
Sometimes i get ECONNRESET, sometimes ECONNABORT, and sometimes recv
simply return an empty string.

I noticed that you use 'read' and 'write' in your example. This puts
the socket into buffered mode. The application may read more data than
your script has read, and hence the buffer in the OS is empty. Simply
converting to 'recv' and 'send' may improve your case, but and error
on 'send' is still not guaranteed.

If you are very worried about data getting delivered, I suggest using
this method from the Winsock FAQ [1]:

1. Finish sending data.
2. Call shutdown() with the how parameter set to 1. (Socket#shutdown)
3. Loop on recv() until it returns 0. (Empty string in Ruby)
4. Call closesocket(). (Socket#close)

This way, recv() will throw an error if there is *unacknowledged*
data. If you employ the same method on the server, recv() will give
you all the data that the client has sent.

[1] http://tangentsoft.net/wskfaq/newbie.htm...

Lars