[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

writing to unix socket

Roeland Moors

12/26/2004 9:45:00 PM

I'm trying to create something that writes to a socket.
This is my code:

require 'socket'
sock = Socket.new(Socket::PF_UNIX, Socket::SOCK_STREAM, 0)
sock.connect(Socket::sockaddr_un(device))
sock.puts('VERSION')
sock.close

This works sometimes, but sometimes it don't and then I get this
error:
test.rb:4:in `write': Broken pipe (Errno::EPIPE)
from test.rb:4:in `puts'
from test.rb:4

I can get it to work always if i put 'sleep 0.1' after
connecting. But way do I have to do this. Is there a better
method?

--
Roeland


3 Answers

mfuhr

12/26/2004 11:47:00 PM

0

Roeland Moors <roelandmoors@telenet.be> writes:

> require 'socket'
> sock = Socket.new(Socket::PF_UNIX, Socket::SOCK_STREAM, 0)
> sock.connect(Socket::sockaddr_un(device))
> sock.puts('VERSION')
> sock.close
>
> This works sometimes, but sometimes it don't and then I get this
> error:
> test.rb:4:in `write': Broken pipe (Errno::EPIPE)
> from test.rb:4:in `puts'
> from test.rb:4

A write fails with EPIPE if the peer has already closed its side
of the connection.

> I can get it to work always if i put 'sleep 0.1' after
> connecting. But way do I have to do this. Is there a better
> method?

Using sleep to synchronize activities should be a warning that
something is wrong; if it works then it's more likely by accident
than by design.

What's on the other end of the connection? If the peer closes its
side before you call puts() then you'll get EPIPE. It's odd that
sleeping for 0.1 seconds apparently fixes the problem; I'd have to
think about it to see if I could contrive a situation where that
would happen.

What OS are you using? Have you run a process trace on the peer
to see what it does after it accepts your connection?

--
Michael Fuhr
http://www.fuhr.o...

Roeland Moors

12/27/2004 9:12:00 AM

0

On Mon, Dec 27, 2004 at 08:52:01AM +0900, Michael Fuhr wrote:
> Roeland Moors <roelandmoors@telenet.be> writes:
>
> > require 'socket'
> > sock = Socket.new(Socket::PF_UNIX, Socket::SOCK_STREAM, 0)
> > sock.connect(Socket::sockaddr_un(device))
> > sock.puts('VERSION')
> > sock.close
> >
> > This works sometimes, but sometimes it don't and then I get this
> > error:
> > test.rb:4:in `write': Broken pipe (Errno::EPIPE)
> > from test.rb:4:in `puts'
> > from test.rb:4
>
> A write fails with EPIPE if the peer has already closed its side
> of the connection.
>

It looks more like the connection isn't ready yet. Is this
possible?
Reading works just fine, but that's probably because it has to
wait for input.

> > I can get it to work always if i put 'sleep 0.1' after
> > connecting. But way do I have to do this. Is there a better
> > method?
>
> Using sleep to synchronize activities should be a warning that
> something is wrong; if it works then it's more likely by accident
> than by design.
>
> What's on the other end of the connection? If the peer closes its
> side before you call puts() then you'll get EPIPE. It's odd that
> sleeping for 0.1 seconds apparently fixes the problem; I'd have to
> think about it to see if I could contrive a situation where that
> would happen.
>

I'm trying to send a command to a device created by lirc:
http://www.lirc.org/html/technical.html#ap...

> What OS are you using?
OS:
Debian sarge
uname -a:
Linux server 2.6.8 #1 Mon Sep 6 20:57:44 CEST 2004 i686 GNU/Linux
ruby --version:
ruby 1.8.2 (2004-12-06) [i386-linux]

> Have you run a process trace on the peer
> to see what it does after it accepts your connection?
>
Could you explain this a bit more?
Or point me to some documentation on how to do this?


--
Roeland


mfuhr

12/27/2004 4:42:00 PM

0

Roeland Moors <roelandmoors@telenet.be> writes:

> On Mon, Dec 27, 2004 at 08:52:01AM +0900, Michael Fuhr wrote:
> >
> > A write fails with EPIPE if the peer has already closed its side
> > of the connection.
>
> It looks more like the connection isn't ready yet. Is this
> possible?

If nobody's listening on the socket then connect() should fail with
ECONNREFUSED. If the socket's listen queue is full then connect()
should either block or fail with ECONNREFUSED (behavior varies
depending on the OS). If connect() succeeded, then the connection
should be "ready" enough to use.

I still haven't been able to contrive a situation where writing
immediately fails with EPIPE but writing after a brief sleep works,
so that remains a mystery. Anybody? (Please test guesses and show
server and client code that duplicates the behavior.) That might
be a question for comp.unix.programmer or comp.protocols.tcp-ip,
although AF_UNIX might not be appropriate for the latter.

Does the peer also listen on an AF_INET socket? If so, have you
tested your client with that?

> Reading works just fine, but that's probably because it has to
> wait for input.

Reading when? Your example didn't show that.

> > What's on the other end of the connection?
>
> I'm trying to send a command to a device created by lirc:
> http://www.lirc.org/html/technical.html#ap...

Have you checked that product's documentation, FAQ, list archives,
and/or source code? Your problems might be more related to that
product than to Ruby, so you might get more help on their mailing
list.

> > Have you run a process trace on the peer
> > to see what it does after it accepts your connection?
> >
> Could you explain this a bit more?
> Or point me to some documentation on how to do this?

I don't use Linux much but I think "man strace" should point you
in the right direction.

--
Michael Fuhr
http://www.fuhr.o...