使用 Python 从 Unix 套接字连接读取和写入

问题描述 投票:0回答:3

我正在使用 Python 试验 Unix 套接字。我想创建一个创建并绑定到套接字的服务器,等待命令并发送响应。

客户端将连接到套接字,发送一个命令,打印响应并关闭连接。

这就是我在服务器端做的事情:

# -*- 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()

但是当我试着听的时候我得到了

socket.error: [Errno 95] Operation not supported

unix sockets支持监听吗?否则,怎样才是读写兼顾的正确方式呢?

感谢任何帮助:)

python sockets unix-socket
3个回答
19
投票

SOCK_DGRAM
套接字不听,他们只是绑定。将插座类型更改为
SOCK_STREAM
,您的
listen()
将工作。

查看 PyMOTW Unix 域套接字 (

SOCK_STREAM
) 与 PyMOTW 用户数据报客户端和服务器 (
SOCK_DGRAM
)


6
投票
#!/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()

修复了你的其他问题......和 SOCK_DGRAM......


0
投票

我有办法使用 python 将 af-unix 套接字转发到 af-inet 套接字:

    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]))
© www.soinside.com 2019 - 2024. All rights reserved.