19

I'm experimenting with Unix sockets using Python. I want to create a server that creates and binds to a socket, awaits for commands and sends a response.

The client would connect to the socket, send one command, print the response and close the connection.

This is what I'm doing server side:

# -*- coding: utf-8 -*-
import socket
import os, os.path
import time
from collections import deque    

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

server = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
server.bind("/tmp/socket_test.s")
while True:
  server.listen(1)
  conn, addr = server.accept()
  datagram = conn.recv(1024)
  if datagram:
    tokens = datagram.strip().split()
    if tokens[0].lower() == "post":
      flist.append(tokens[1])
      conn.send(len(tokens) + "")
    else if tokens[0].lower() == "get":
      conn.send(tokens.popleft())
    else:
      conn.send("-1")
    conn.close()

But I get socket.error: [Errno 95] Operation not supported when trying to listen.

Do unix sockets support listening? Otherwise, what would be the right way for both reading and writing?

Any help appreciated :)

3 Answers 3

20

SOCK_DGRAM sockets don't listen, they just bind. Change the socket type to SOCK_STREAM and your listen() will work.

Check out PyMOTW Unix Domain Sockets (SOCK_STREAM) vs. PyMOTW User Datagram Client and Server (SOCK_DGRAM)

Sign up to request clarification or add additional context in comments.

Comments

8
#!/usr/bin/python

import socket
import os, os.path
import time
from collections import deque

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

server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
server.bind("/tmp/socket_test.s")
while True:
  server.listen(1)
  conn, addr = server.accept()
  datagram = conn.recv(1024)
  if datagram:
    tokens = datagram.strip().split()
    if tokens[0].lower() == "post":
      flist.append(tokens[1])
      conn.send(len(tokens) + "")
    elif tokens[0].lower() == "get":
      conn.send(tokens.popleft())
    else:
      conn.send("-1")
    conn.close()

Fixed you else... and SOCK_DGRAM...

Comments

0

I have a way to farward af-unix socket to af-inet socket by using python:

    def _ip_port_forward_by_using_a_socket_file(self, socket_file_path: str, to_ip_port: str):
        """
        socket_file_path: string
            a socket file like /tmp/message.socket
        to_ip_port: string
            It is something like this: 127.0.0.1:22
        
        It is normally used to read wire socket from usb line, like '/dev/usb0'. 
        But you can also use it twice to forward data between two isolated container where file sharing is possible.
        """
        import socket
        import threading
        import os

        if (os.path.exists(socket_file_path)):
            os.remove(socket_file_path)

        def handle(buffer: Any, direction: Any, src_address: Any, src_port: Any, dst_address: Any, dst_port: Any):
            '''
            intercept the data flows between local port and the target port
            '''
            return buffer

        def transfer(src: Any, dst: Any, direction: Any):
            error = None
            try:
                src_address, src_port = src.getsockname()
                dst_address, dst_port = dst.getsockname()
            except Exception as e:
                error = True
                print(e)
            while True:
                try:
                    buffer = src.recv(4096)
                    if len(buffer) > 0:
                        if error == True:
                            dst.send(buffer)
                        else:
                            dst.send(handle(buffer, direction, src_address, src_port, dst_address, dst_port)) #type: ignore
                except Exception as e:
                    print("error: ", repr(e))
                    break
            src.close()
            dst.close()

        def server(socket_file_path: str, remote_host: Any, remote_port: Any):
            server_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            server_socket.bind(socket_file_path)
            server_socket.listen(0x40)
            while True:
                src_socket, src_address = server_socket.accept()
                try:
                    dst_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    dst_socket.connect((remote_host, remote_port))
                    s = threading.Thread(target=transfer, args=(dst_socket, src_socket, False))
                    r = threading.Thread(target=transfer, args=(src_socket, dst_socket, True))
                    s.start()
                    r.start()
                except Exception as e:
                    print("error: ", repr(e))

        to_ = to_ip_port.split(":")
        server(socket_file_path=socket_file_path, remote_host=to_[0], remote_port=int(to_[1]))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.