用socket.AF_UNIX做进程间通信(IPC)

Last Updated: 2023-03-22 07:51:42 Wednesday

-- TOC --

一直以来socket编程,用的都是socket.AF_INET address family,包括在同一主机上多进程间的通信,其实,AF_UNIX更适合IPC领域,性能更好!

socket.AF_UNIX的另一个名称,是UNIX Domain Sockets,我们用netstat命令看到的很多Active UNIX domain sockets,它们都是这一类。这类socket通信,地址是一个文件,我们常常看到的*.sock文件(与后缀无关,只是命名习惯),就是被UNIX domain sockets用来通信的地址。

下面是一段测试代码:

import socket
import threading


s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind('abc.sock')
s.listen()


def handle_tcp(sock, addr):
    print("new connection from ", str(addr), type(addr), len(addr))
    sock.send(b'Welcome!')

    while True:
        data = sock.recv(1024)
        if not data:
            break
        sock.send(b'Hello, %s!' % data)
    sock.close()


while True:
    sock, addr = s.accept()
    t = threading.Thread(target=handle_tcp, args=(sock, addr))
    t.start()

s.bind('abc.sock')这行代码会在当前目录下创建abc.sock文件,并绑定。

socket的其它接口使用都是一样的,有个细节要注意,s.accept()返回的addr,是个长度为0的str对象

client调用connect的时候,使用相同的socket文件:

import socket
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect('abc.sock')

abc.sock文件:

srwxrwxr-x  1 xinlin xinlin      0 4月   2 10:02 abc.sock=

socket文件有个=号,命名管道文件有个|。它们都是一个特殊文件,它们都用于IPC进程间通信。

测试时发现,abc.sock文件需要手动删除,否则再次运行此程序,会出现地址已被占用的错误:

$ python3 mt_unix_sock.py
Traceback (most recent call last):
  File "mt_unix_sock.py", line 7, in <module>
    s.bind('abc.sock')
OSError: [Errno 98] Address already in use

看来,这行代码s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)没有起作用。

与AF_INET比较

本文链接:https://cs.pynote.net/net/tcp/202204021/

-- EOF --

-- MORE --