Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to set up a 'listening' Unix domain socket

113 views
Skip to first unread message

Robert Latest

unread,
Mar 22, 2021, 6:06:49 AM3/22/21
to
Hello,

I'm trying to set up a server that receives data on a Unix domain socket using
the code below.

import os from socketserver import UnixStreamServer, StreamRequestHandler

SOCKET = '/tmp/test.socket'

class Handler(StreamRequestHandler):

def handle(self): data = selr.rfile.read() print(data)

if os.path.exists(SOCKET): os.unlink(SOCKET) with UnixStreamServer(SOCKET,
Handler) as server: server.serve_forever()


However, when I try to send somthing to that socket, I get this error message:

$ echo "Hello" | socat - UNIX-SENDTO:/tmp/test.socket 2021/03/22 11:03:22
socat[2188] E sendto(5, 0x55a22f414990, 6, 0, AF=1 "/tmp/test.socket", 18):
Protocol wrong type for socket

I don't understand that error. Here's /tmp/test.socket:

$ stat /tmp/test.socket
File: ‘/tmp/test.socket’
Size: 0 Blocks: 0 IO Block: 4096 socket
Device: fd00h/64768d Inode: 201443577 Links: 1
Access: (0775/srwxrwxr-x) Uid: ( 1001/ dh) Gid: ( 1001/ dh)
Context: unconfined_u:object_r:user_tmp_t:s0
Access: 2021-03-22 09:47:49.516298102 +0100
Modify: 2021-03-22 09:47:49.516298102 +0100
Change: 2021-03-22 09:47:49.516298102 +0100
Birth: -

Sadly all examples I can find on the web are for TCP sockets, not Unix domain.

Any tips?
robert

Chris Angelico

unread,
Mar 22, 2021, 7:27:22 AM3/22/21
to
On Mon, Mar 22, 2021 at 9:11 PM Robert Latest via Python-list
<pytho...@python.org> wrote:
>
> Hello,
>
> I'm trying to set up a server that receives data on a Unix domain socket using
> the code below.
>
> import os from socketserver import UnixStreamServer, StreamRequestHandler
>
> SOCKET = '/tmp/test.socket'
>
> class Handler(StreamRequestHandler):
>
> def handle(self): data = selr.rfile.read() print(data)
>
> if os.path.exists(SOCKET): os.unlink(SOCKET) with UnixStreamServer(SOCKET,
> Handler) as server: server.serve_forever()

Hmm, your formatting's messed up, but the code looks fine to me. (Be
aware that you seem to have a "selr" where it should be "self".)

> However, when I try to send somthing to that socket, I get this error message:
>
> $ echo "Hello" | socat - UNIX-SENDTO:/tmp/test.socket 2021/03/22 11:03:22
> socat[2188] E sendto(5, 0x55a22f414990, 6, 0, AF=1 "/tmp/test.socket", 18):
> Protocol wrong type for socket
>

Not familiar with socat, but here's some simple Python code to trigger
your server:

>>> import socket
>>> sock = socket.socket(socket.AF_UNIX)
>>> sock.connect("/tmp/test.socket")
>>> sock.send(b"Hello, world")
12
>>> sock.close()
>>>

Once you close the socket, the request handler should respond.

ChrisA

Robert Latest

unread,
Mar 22, 2021, 7:44:06 AM3/22/21
to
Chris Angelico wrote:
>
> Hmm, your formatting's messed up, but the code looks fine to me. (Be aware
> that you seem to have a "selr" where it should be "self".)

Didn't catch that because my program didn't even get to that point ;-)

>
>> However, when I try to send somthing to that socket, I get this error
>> message:
>>
>> $ echo "Hello" | socat - UNIX-SENDTO:/tmp/test.socket 2021/03/22 11:03:22
>> socat[2188] E sendto(5, 0x55a22f414990, 6, 0, AF=1 "/tmp/test.socket", 18):
>> Protocol wrong type for socket
>>
>
> Not familiar with socat, but here's some simple Python code to trigger your
> server:
>
>>>> import socket sock = socket.socket(socket.AF_UNIX)
>>>> sock.connect("/tmp/test.socket") sock.send(b"Hello, world")
> 12
>>>> sock.close()
>>>>

Works perfectly, thanks! I'm probably not using socat right.

robert

Robert Latest

unread,
Mar 22, 2021, 11:02:21 AM3/22/21
to
> Chris Angelico wrote:

[Helpful stuff]

I'm actually trying to implement a SocketHandler for a Python logger. However,
I can't get my handler on the client side to send anything. Do I need to
subclass logging.SocketHandler and fill the various methods with meaning? The
documentation doesn't say so.

I've noticed that when the server is not running, logging.SocketHandler creates
the socket. I don't understand why it would; isn't it the server's job to
create the socket?

################## CLIENT ############################

import socket
import pickle
from logging import getLogger
from logging.handlers import SocketHandler

SOCKET = '/tmp/test.socket'

# This doesn't send anything to the socket
_log = getLogger(__name__)
_log.addHandler(SocketHandler(None, SOCKET))
_log.error('Logging something')

# String gets sent to socket
sock = socket.socket(socket.AF_UNIX)
sock.connect(SOCKET)
sock.send(b"Hello, world")
sock.close()

# Pickled object works fine
sock = socket.socket(socket.AF_UNIX)
sock.connect(SOCKET)
sock.send(pickle.dumps(dict(a=1)))
sock.close()


################## SERVER ############################

import os
import pickle
from socketserver import UnixStreamServer, StreamRequestHandler

SOCKET = '/tmp/test.socket'

class Handler(StreamRequestHandler):

def handle(self):
data = self.rfile.read()
try:
obj = pickle.loads(data)
except:
print('Unpickled: ', data)
else:
print('Pickled: ', type(obj))
0 new messages