Skip to main content

Unix Domain Socket

·210 words·1 min

Unix domain socket 或者 IPC socket是一种终端,可以使同一台操作系统上的两个或多个进程进行数据通信。与管道相比,Unix domain socket 既可以使用字节流,又可以使用数据队列,而管道通信则只能使用字节流。Unix domain socket的接口和Internet socket很像,但它不使用网络底层协议来通信。Unix domain socket 的功能是POSIX操作系统里的一种组件。
Unix domain socket 使用系统文件的地址来作为自己的身份。它可以被系统进程引用。所以两个进程可以同时打开一个Unix domain sockets来进行通信。不过这种通信方式是发生在系统内核里而不会在网络里传播。【from wiki】

如果从编程的角度来看,Unix domain socket和TCP/IP之间有两个重要的不同。第一点,socket的地址是文件路径,而不是一个包含ip和端口的元组。其次, 在文件系统创建的代表socket的文件在socket关闭后依然存在,并且需要在每次服务器启动时删除。

server.py

import socket
import sys
import os

SERVER_PATH = './uds_socket'

# Make sure the socket does not already exist
if os.path.exists(SERVER_PATH):
	os.remove(SERVER_PATH)
print >>sys.stderr ,'starting unix domain socket server'

# Create a UDS socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
# Bind the socket to the port
sock.bind(SERVER_PATH)
# Listen for incoming conns
sock.listen(2)
print >>sys.stderr, 'Listening on path: %s' % SERVER_PATH

while True:
    conn, addr = sock.accept()
    try:
        while True:
            data = conn.recv(1024)
            if data:
                print >>sys.stderr, 'received [%s]' % data
                conn.sendall(data)
            else:
                break
    except Exception,e:
     	 print e
    finally:
        conn.close()

client.py

import socket
import sys

# Create a UDS socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
# Connect the socket to the port where the server is listening
server_address = './uds_socket'
print >>sys.stderr, 'connecting to %s' % server_address
try:
    sock.connect(server_address)
except socket.error, msg:
    print >>sys.stderr, msg
    sys.exit(1)
    
try:
    # Send data
    message = 'This is the message, This will be echoed back'
    print >>sys.stderr, 'sending [%s]' % message
    sock.sendall(message)

    amount_received = 0
    amount_expected = len(message)
    
    while amount_received < amount_expected:
        data = sock.recv(1024)
        amount_received += len(data)
        print >>sys.stderr, 'received [%s]' % data

finally:
    print >>sys.stderr, 'closing socket'
    sock.close()