unix domain socket 淺析

unix domain socket

unix domain socket 是在socket架構(gòu)上發(fā)展起來(lái)的用于同一臺(tái)主機(jī)的進(jìn)程間通訊(IPC: Inter-Process Communication),它不需要經(jīng)過(guò)網(wǎng)絡(luò)協(xié)議棧,不需要打包拆包、計(jì)算校驗(yàn)和、維護(hù)序號(hào)和應(yīng)答等,只是將應(yīng)用層數(shù)據(jù)從一個(gè)進(jìn)程拷貝到另一個(gè)進(jìn)程。UNIX Domain Socket有SOCK_DGRAM或SOCK_STREAM兩種工作模式,類似于UDP和TCP,但是面向消息的UNIX Domain Socket也是可靠的,消息既不會(huì)丟失也不會(huì)順序錯(cuò)亂。

UNIX Domain Socket可用于兩個(gè)沒(méi)有親緣關(guān)系的進(jìn)程,是全雙工的,是目前使用最廣泛的IPC機(jī)制,比如X Window服務(wù)器和GUI程序之間就是通過(guò)UNIX Domain Socket通訊的。

UNIX Domain socket與網(wǎng)絡(luò)socket類似,可以與網(wǎng)絡(luò)socket對(duì)比應(yīng)用。

上述二者編程的不同如下:

  • address family為AF_UNIX
  • 因?yàn)閼?yīng)用于IPC,所以UNIXDomain socket不需要IP和端口,取而代之的是文件路徑來(lái)表示“網(wǎng)絡(luò)地址”。這點(diǎn)體現(xiàn)在下面兩個(gè)方面。
  • 地址格式不同,UNIXDomain socket用結(jié)構(gòu)體sockaddr_un表示,是一個(gè)socket類型的文件在文件系統(tǒng)中的路徑,這個(gè)socket文件由bind()調(diào)用創(chuàng)建,如果調(diào)用bind()時(shí)該文件已存在,則bind()錯(cuò)誤返回。
  • UNIX Domain Socket客戶端一般要顯式調(diào)用bind函數(shù),而不象網(wǎng)絡(luò)socket一樣依賴系統(tǒng)自動(dòng)分配的地址??蛻舳薭ind的socket文件名可以包含客戶端的pid,這樣服務(wù)器就可以區(qū)分不同的客戶端。

下面用python代碼演示uds的使用

Python代碼演示

服務(wù)端

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Created on 12/11/17 11:55 AM
@author: Chen Liang
@function: socket_echo_server_uds
"""

import sys

reload(sys)
sys.setdefaultencoding('utf-8')
import socket
import os

server_address = './uds_socket'

# Make sure the socket does not already exist
try:
    os.unlink(server_address)
except OSError:
    if os.path.exists(server_address):
        raise

# Create a UDS socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)

# Bind the socket to the address
print('starting up on {}'.format(server_address))
sock.bind(server_address)

# Listen for incoming connections
sock.listen(1)

while True:
    # Wait for a connection
    print('waiting for a connection')
    connection, client_address = sock.accept()
    try:
        print('connection from', client_address)

        # Receive the data in small chunks and retransmit it
        while True:
            data = connection.recv(16)
            print('received {!r}'.format(data))
            if data:
                print('sending data back to the client')
                connection.sendall(data)
            else:
                print('no data from', client_address)
                break

    finally:
        # Clean up the connection
        connection.close()

客戶端

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Created on 12/11/17 11:55 AM
@author: Chen Liang
@function: socket_echo_client_uds
"""

import sys

reload(sys)
sys.setdefaultencoding('utf-8')


import socket
import sys

# Create a UDS socket
sock = socket.socket(family=socket.AF_UNIX, type=socket.SOCK_STREAM)

# Connect the socket to the port where the server is listening
server_address = './uds_socket'
print('connecting to {}'.format(server_address))
try:
    sock.connect(server_address)
except socket.error as msg:
    print(msg)
    sys.exit(1)

try:

    # Send data
    message = b'This is the message.  It will be repeated.'
    print('sending {!r}'.format(message))
    sock.sendall(message)

    amount_received = 0
    amount_expected = len(message)

    while amount_received < amount_expected:
        data = sock.recv(16)
        amount_received += len(data)
        print('received {!r}'.format(data))

finally:
    print('closing socket')
    sock.close()

客戶端一次發(fā)送,服務(wù)端分批返回。

服務(wù)端輸出結(jié)果如下

root@ubuntu:~/PycharmProjects/python_scripts# python socket_echo_server_uds.py 
starting up on ./uds_socket
waiting for a connection
('connection from', '')
received 'This is the mess'
sending data back to the client
received 'age.  It will be'
sending data back to the client
received ' repeated.'
sending data back to the client
received ''
('no data from', '')
waiting for a connection

客戶端輸出結(jié)果如下

root@ubuntu:~/PycharmProjects/python_scripts# python socket_echo_client_uds.py 
connecting to ./uds_socket
sending 'This is the message.  It will be repeated.'
received 'This is the mess'
received 'age.  It will be'
received ' repeated.'
closing socket

查看套接字文件的類型如下

root@ubuntu:~/PycharmProjects/python_scripts# ls -l ./uds_socket
srwxr-xr-x 1 root root 0 Dec 11 13:45 ./uds_socket

可見(jiàn)uds文件是socket類型。具體的linux文件類型有以下幾種:

Linux的文件類型有以下幾種:

文件類型 ls -l顯示
普通文件 -
目錄 d
符號(hào)鏈接 l
字符設(shè)備 c
塊設(shè)備 b
套接字 s
命名管道 p

參考:


念念不忘,必有回響,小伙伴們幫我點(diǎn)個(gè)贊吧,非常感謝。

我是職場(chǎng)亮哥,YY高級(jí)軟件工程師、四年工作經(jīng)驗(yàn),拒絕咸魚(yú)爭(zhēng)當(dāng)龍頭的斜杠程序員。

聽(tīng)我說(shuō),進(jìn)步多,程序人生一把梭

如果有幸能幫到你,請(qǐng)幫我點(diǎn)個(gè)【贊】,給個(gè)關(guān)注,如果能順帶評(píng)論給個(gè)鼓勵(lì),將不勝感激。

職場(chǎng)亮哥文章列表:更多文章

本人所有文章、回答都與版權(quán)保護(hù)平臺(tái)有合作,著作權(quán)歸職場(chǎng)亮哥所有,未經(jīng)授權(quán),轉(zhuǎn)載必究!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容