Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read and write from Unix socket connection with Python

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 :)

like image 796
aleknaui Avatar asked Feb 16 '17 01:02

aleknaui


People also ask

How do I interact with a UNIX socket?

Unlike standard FIFOs or pipes, work with sockets is done using the sockets interface as opposed to the file interface. The -U parameter tells netcat to use a Unix Socket file, which we have specified. The -l parameter tells it to act as the server-side and listen on the specified socket for incoming connections.


2 Answers

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)

like image 124
pbuck Avatar answered Oct 14 '22 09:10

pbuck


#!/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...

like image 23
Malan Avatar answered Oct 14 '22 09:10

Malan