467,077 Members | 1,154 Online
Bytes | Developer Community
Ask Question

Home New Posts Topics Members FAQ

Post your question to a community of 467,077 developers. It's quick & easy.

Bidirectional communication over unix socket (named pipe)

Hi, I feel like I should apologize in advance because I must be missing
something fairly basic and fundamental here. I don't have a book on
Python network programming (yet) and I haven't been able to find an
answer on the net so far.

I am trying to create a pair of programs, one (the client) will be
short-lived (fairly) and the second (server) will act as a cache for
the client. Both will run on the same machine, so I think a simple file
socket is the easiest and most reliable method.

The problem I have is that the client can send to the server, but the
server can't send back to the client because it gets this error:

socket.error: (107, 'Transport endpoint is not connected')

This is despite the client waiting on a socket.recv() statement. Is
the client really not connected, or is the server unaware of the
connection? And how do I fix this?

I was able to get this working by switching to AF_INET, but that is not
what I want.

Unix sockets are bidirectional, correct? I have never programmed one,
but I know that programs like clamav use a socket to receive an email
to scan and return the result.

Any help would be greatly appreciated!

Jeff

*** server.py ***
#!/usr/bin/python
import socket
import os, os.path
import time

if os.path.exists("/tmp/mysock"): os.remove("/tmp/mysock")

server = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
server.bind("/tmp/mysock")

while True:
datagram = server.recv(1024)
if not datagram:
break
print datagram
# the preceeding works, and I see the TEST TEST TEST statement the
client sent

time.sleep(2)
# it dies on the next statement.
server.send("Thank you\n")
server.close()
if os.path.exists("/tmp/mysock"): os.remove("/tmp/mysock")
*** client.py: ***
#!/usr/bin/python

import socket

client = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
client.connect("/tmp/mysock")
TX = "TEST TEST TEST"
TX_sent = client.send(TX)

if TX_sent <> len(TX): print "TX incomplete"

while True:
print "Waiting..."
datagram = client.recv(1024)
# the client sits here forever, I see the "waiting appear" but
it doesn't advance beyond
# the recv statement.
if not datagram:
break
print "Received: ",datagram

client.close()

Mar 8 '06 #1
  • viewed: 8940
Share:
6 Replies

OK, never fails that I find a solution once I post a problem. If I use
a stream rather than a datagram, it seems to work fine.

So... for my education, how would I make this work with a datagram, if
I insisted on doing it that way?

Mar 8 '06 #2
In article <11**********************@z34g2000cwc.googlegroups .com>,
"J Rice" <ri**********@gmail.com> wrote:
The problem I have is that the client can send to the server, but the
server can't send back to the client because it gets this error:

socket.error: (107, 'Transport endpoint is not connected')

This is despite the client waiting on a socket.recv() statement. Is
the client really not connected, or is the server unaware of the
connection? And how do I fix this?


You can either connect() as well as bind(), or use
sendto(data, file)

Donn Cave, do**@u.washington.edu
Mar 8 '06 #3

Hi Donn,
Not sure I fully understand your suggestion. bind() only works once --
I can't bind again in the client. Same thing with connect() -- once I
issue a connect in the server, it rejects it in the client.

Doing this as a stream works for what I want, but I would like to
understand why it didn't work with datagram.

Mar 8 '06 #4
In article <11**********************@i40g2000cwc.googlegroups .com>,
"J Rice" <ri**********@gmail.com> wrote:
Hi Donn,
Not sure I fully understand your suggestion. bind() only works once --
I can't bind again in the client. Same thing with connect() -- once I
issue a connect in the server, it rejects it in the client.

Doing this as a stream works for what I want, but I would like to
understand why it didn't work with datagram.


Right, bind should be on one end only, as it creates
the actual socket file.

Connect works on either end, with SOCK_DGRAM. From
man 2 connect:

The parameter s is a socket. If it is of type SOCK_DGRAM,
this call specifies the peer with which the socket is to be
associated; this address is that to which datagrams are to
be sent, and the only address from which datagrams are to be
received. If the socket is of type SOCK_STREAM, this call
attempts to make a connection to another socket.

However, even if we're straight on this, I confess I
have only addressed your question about the unconnected
endpoint.

The other part of the problem remains, as I don't know
how to get data to actually go both ways. I was a little
surprised by this, and have not been able to scare up any
explicit documentation, but the only example program I
could find for two-way UNIX domain datagram IPC, uses two
sockets, not one -
http://docs.hp.com/en/B2355-90136/ch07s06.html

Donn Cave, do**@u.washington.edu
Mar 8 '06 #5

Donn Cave wrote:
The other part of the problem remains, as I don't know
how to get data to actually go both ways.


The problem here is that datagram sockets don't send data from one
process to another, they send data from one address to another. In
this case, the client isn't able to receive data through it's socket
because the socket isn't bound any address. Calling connect() on the
datagram socket doesn't give the socket an address to receive data
with, just a default address to send data to. Since the server's
socket is the only socket bound to "/tmp/mysock" it's the only the only
process that can receive datagrams sent to that address. That includes
any datagrams the server itself sends to the address.

You need multiple Unix domain address so each process has an address it
can receive data with, and an address other than it's own that it can
send data to.

Ross Ridge

Mar 9 '06 #6
Thank you, that answers my question! And it works fine with stream, so
I can do what I want as well.

Mar 11 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Rajarshi Guha | last post: by
5 posts views Thread by richard | last post: by
reply views Thread by Spiros | last post: by
3 posts views Thread by EricR | last post: by
2 posts views Thread by FB's .NET Dev PC | last post: by
reply views Thread by EricR | last post: by
reply views Thread by olaf.dietsche | last post: by
14 posts views Thread by Rochester | last post: by
reply views Thread by jeb2000 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.