Unix Domain Socket

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