linux一切皆文件之Unix domain socket描述符(二)

一过吻、知識(shí)準(zhǔn)備

1、在linux中蔗衡,一切皆為文件纤虽,所有不同種類的類型都被抽象成文件(比如:塊設(shè)備,socket套接字绞惦,pipe隊(duì)列)
2逼纸、操作這些不同的類型就像操作文件一樣,比如增刪改查等
3济蝉、主要用于:運(yùn)行在同一臺(tái)機(jī)器上的2個(gè)進(jìn)程相互之間的數(shù)據(jù)通信
4杰刽、它們和網(wǎng)絡(luò)文件描述符非常相似(比如:TCP socket)菠发,他們的通信發(fā)生在操作系統(tǒng)內(nèi)核


二、環(huán)境準(zhǔn)備

組件 版本
OS CentOS Linux release 7.5.1804


三贺嫂、Unix domain socket 文件描述符

先準(zhǔn)備2個(gè)腳本:
server.py主要用于建立客戶端的連接請(qǐng)求滓鸠,并且接收客戶端傳來的數(shù)據(jù),然后將收到的數(shù)據(jù)回傳給客戶端
client.py每隔1秒向服務(wù)端發(fā)送一次'hello world'

server.py:

import socket

server_addr = '/tmp/server.sock'

sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.bind(server_addr)
sock.listen(0)

while True:
    conn, clientAddr = sock.accept()
    while True:
        data = conn.recv(100)
        conn.sendall(data)

client.py:

import socket
import time

server_addr = '/tmp/server.sock'

sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect(server_addr)

while True:
    message = 'hello world!'
    sock.sendall(message)
    sock.recv(100)
    time.sleep(1)

sock.close()

先看下server.py的狀態(tài):

[root@localhost ~]# python /tmp/server.py &
[1] 2554
[root@localhost ~]# ls -l /proc/2554/fd
total 0
lrwx------ 1 root root 64 Nov  5 02:39 0 -> /dev/pts/0
lrwx------ 1 root root 64 Nov  5 02:39 1 -> /dev/pts/0
lrwx------ 1 root root 64 Nov  5 02:39 2 -> /dev/pts/0
lrwx------ 1 root root 64 Nov  5 02:39 3 -> socket:[28724]
[root@localhost ~]# grep 28724 /proc/net/unix
ffff90d8ba564000: 00000002 00000000 00010000 0001 01 28724 /tmp/server.sock
[root@localhost ~]# lsof -n | grep 28724
python    2554         root    3u     unix 0xffff90d8ba564000       0t0      28724 /tmp/server.sock
[root@localhost ~]# netstat -anp | grep 28724
unix  2      [ ACC ]     STREAM     LISTENING     28724    2554/python         /tmp/server.sock

進(jìn)程2554創(chuàng)建了打開了unix domain socket描述符(3 -> socket:[19803])涝婉,并且通過該描述符哥力,打開了/tmp/server.sock文件,其主要作用是用于監(jiān)聽

我們運(yùn)行client.py并觀察狀態(tài)

[root@localhost ~]# python /tmp/client.py &
[2] 2555
[root@localhost ~]# ls -l /proc/2555/fd
total 0
lrwx------ 1 root root 64 Nov  5 02:39 0 -> /dev/pts/0
lrwx------ 1 root root 64 Nov  5 02:39 1 -> /dev/pts/0
lrwx------ 1 root root 64 Nov  5 02:39 2 -> /dev/pts/0
lrwx------ 1 root root 64 Nov  5 02:39 3 -> socket:[28728]
[root@localhost ~]# grep 28728 /proc/net/unix
ffff90d8b95b0400: 00000003 00000000 00000000 0001 03 28728
[root@localhost ~]# lsof -n | grep 28728
python    2555         root    3u     unix 0xffff90d8b95b0400       0t0      28728 socket

與server.py的行為差不多墩弯。client.py也創(chuàng)建了unix domain socket描述符3 -> socket:[28728]吩跋,通過socket:[18974],找到一條socket

查看server.py發(fā)生的變化:

[root@localhost ~]# ls -l /proc/2554/fd
total 0
lrwx------ 1 root root 64 Nov  5 02:39 0 -> /dev/pts/0
lrwx------ 1 root root 64 Nov  5 02:39 1 -> /dev/pts/0
lrwx------ 1 root root 64 Nov  5 02:39 2 -> /dev/pts/0
lrwx------ 1 root root 64 Nov  5 02:39 3 -> socket:[28724]
lrwx------ 1 root root 64 Nov  5 02:39 4 -> socket:[28725]

server.py新增了一個(gè)4 -> socket:[28725]渔工,這是剛才client.py連接成功之后server.py新打開的描述符

[root@localhost ~]# lsof -n | grep -E '28728|28724|28725'
python    2554         root    3u     unix 0xffff90d8ba564000       0t0      28724 /tmp/server.sock
python    2554         root    4u     unix 0xffff90d8b95b0000       0t0      28725 /tmp/server.sock
python    2555         root    3u     unix 0xffff90d8b95b0400       0t0      28728 socket
[root@localhost ~]# netstat -anp | grep unix | grep -E '28728|28724|28725'
unix  2      [ ACC ]     STREAM     LISTENING     28724    2554/python          /tmp/server.sock
unix  3      [ ]         STREAM     CONNECTED     28725    2554/python          /tmp/server.sock
unix  3      [ ]         STREAM     CONNECTED     28728    2555/python

到目前為止锌钮,整個(gè)unix domain socket的通信過程已經(jīng)比較清晰的展現(xiàn)了:
● server.py啟動(dòng)之后,打開監(jiān)聽的描述符引矩,等待來自客戶端的連接請(qǐng)求
● client.py啟動(dòng)之后梁丘,與server連接成功,打開一個(gè)描述符用于與server.py通信
● server.py會(huì)再打開一個(gè)描述符用于與client.py進(jìn)行數(shù)據(jù)通信

但是目前還有2個(gè)問題:
(1)/tmp/server.sock到底作用是什么
(2)server與client是怎么進(jìn)行數(shù)據(jù)通信的

問題(1)

● /tmp/server.sock是操作系統(tǒng)的實(shí)體文件旺韭,擁有一個(gè)全局的文件系統(tǒng)描述符氛谜,這個(gè)描述符在操作系統(tǒng)中是唯一的
● server.py啟動(dòng)時(shí)打開了server.sock,就聲名了與server.py建立連接就只能通過server.sock文件
● 這就相當(dāng)于TCP socket中四元組中的兩元(server_ip:server_port

問題(2)

我們來使用strace命令看看server.py的內(nèi)核調(diào)用

[root@localhost tmp]# strace -p 2554
strace: Process 2554 attached
recvfrom(4, "hello world!", 100, 0, NULL, NULL) = 12
sendto(4, "hello world!", 12, 0, NULL, 0) = 12
recvfrom(4, "hello world!", 100, 0, NULL, NULL) = 12
sendto(4, "hello world!", 12, 0, NULL, 0) = 12

recvfrom(<font color=#de171c>4</font>, "hello world!", 100, 0, NULL, NULL) = 12
sendto(<font color=#de171c>4</font>, "hello world!", 12, 0, NULL, 0) = 12
server.py在接收客戶端數(shù)據(jù)的時(shí)候区端,使用了 4 -> socket:[28725]這個(gè)文件描述符

再看client.py的內(nèi)核調(diào)用

[root@localhost tmp]# strace -p 2555
strace: Process 2555 attached
select(0, NULL, NULL, NULL, {0, 996991}) = 0 (Timeout)
sendto(3, "hello world!", 12, 0, NULL, 0) = 12
recvfrom(3, "hello world!", 100, 0, NULL, NULL) = 12
select(0, NULL, NULL, NULL, {1, 0})     = 0 (Timeout)
sendto(3, "hello world!", 12, 0, NULL, 0) = 12

recvfrom(<font color=#de171c>3</font>, "hello world!", 100, 0, NULL, NULL) = 12
sendto(<font color=#de171c>3</font>, "hello world!", 12, 0, NULL, 0) = 12
client.py在與server.py通信的時(shí)候使用了 3 -> socket:[28728]

結(jié)論:
● server.py與client.py連接建立成功之后值漫,都會(huì)各自在自己的進(jìn)程下打開unix domain socket描述符,該描述符來指向?qū)?yīng)的socket內(nèi)存空間(下面簡(jiǎn)稱s_mem
● client.py通過3 -> socket:[28728]织盼,找到s_mem杨何,然后寫入數(shù)據(jù)hello world!
● server.py通過4 -> socket:[28725],找到s_mem沥邻,讀取數(shù)據(jù)hello world!危虱,并且原封不動(dòng)的發(fā)送這串?dāng)?shù)據(jù)給client.py
● client.py通過讀取s_mem,獲取從server.py傳來的數(shù)據(jù)
● 循環(huán)往復(fù)

           client.py                         server.py
           +---------------+                 +---------------+
           |pid:2555       |                 |pid:2554       |
           |    +-----+    |                 |    +-----+    |
           |    |fd:3 |    |                 |    |fd:4 |    |
           |    +-----+    |                 |    +-----+    |
           +---------------+                 +---------------+
                   |                                 |
user space         |                                 |
+---------------------------------------------------------------------+
kernel space       |                                 |
                   |                                 |
                   v                                 v
            +--------------+                  +--------------+
            |socket:[28728]|                  |socket:[28725]|
            +------+-------+                  +------+-------+
                   |                                 |
                   |                                 |
                   v                                 v
                 +------------------------------------+
                 |              socket                |
                 +------------------------------------+


四唐全、小結(jié)

● /tmp/server.sock作為建立unix domain socket連接的唯一標(biāo)識(shí)符
● unix domain socket連接建立完成之后在內(nèi)存開辟一塊空間埃跷,而server與client在這塊內(nèi)存空間中進(jìn)行數(shù)據(jù)傳輸
● 在同一臺(tái)機(jī)器上的進(jìn)程通信,unix domain socket比tcp socket更快邮利,因?yàn)樗恍枰W(wǎng)絡(luò)協(xié)議棧弥雹,不需要打包拆包、計(jì)算校驗(yàn)和近弟、維護(hù)序號(hào)和應(yīng)答等等過程


五缅糟、參考資料

https://en.wikipedia.org/wiki/Unix_domain_socket



至此挺智,本文結(jié)束
在下才疏學(xué)淺祷愉,有撒湯漏水的窗宦,請(qǐng)各位不吝賜教...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過簡(jiǎn)信或評(píng)論聯(lián)系作者二鳄。
  • 序言:七十年代末赴涵,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子订讼,更是在濱河造成了極大的恐慌髓窜,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件欺殿,死亡現(xiàn)場(chǎng)離奇詭異寄纵,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)脖苏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門程拭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人棍潘,你說我怎么就攤上這事恃鞋。” “怎么了亦歉?”我有些...
    開封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵恤浪,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我肴楷,道長(zhǎng)水由,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任阶祭,我火速辦了婚禮绷杜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘濒募。我一直安慰自己鞭盟,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開白布瑰剃。 她就那樣靜靜地躺著齿诉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪晌姚。 梳的紋絲不亂的頭發(fā)上粤剧,一...
    開封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音挥唠,去河邊找鬼抵恋。 笑死,一個(gè)胖子當(dāng)著我的面吹牛宝磨,可吹牛的內(nèi)容都是我干的弧关。 我是一名探鬼主播盅安,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼世囊!你這毒婦竟也來了别瞭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤株憾,失蹤者是張志新(化名)和其女友劉穎蝙寨,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嗤瞎,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡墙歪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了贝奇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片箱亿。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖弃秆,靈堂內(nèi)的尸體忽然破棺而出届惋,到底是詐尸還是另有隱情,我是刑警寧澤菠赚,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布脑豹,位于F島的核電站缰雇,受9級(jí)特大地震影響茬高,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜沫屡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一拌牲、第九天 我趴在偏房一處隱蔽的房頂上張望俱饿。 院中可真熱鬧,春花似錦塌忽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽擦耀。三九已至,卻和暖如春眷蜓,著一層夾襖步出監(jiān)牢的瞬間分瘾,已是汗流浹背吁系。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工德召, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留痊远,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓氏捞,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親冒版。 傳聞我的和親對(duì)象是個(gè)殘疾皇子液茎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容

  • 網(wǎng)絡(luò)編程 一.楔子 你現(xiàn)在已經(jīng)學(xué)會(huì)了寫python代碼捆等,假如你寫了兩個(gè)python文件a.py和b.py,分別去運(yùn)...
    go以恒閱讀 1,999評(píng)論 0 6
  • 大綱 一.Socket簡(jiǎn)介 二.BSD Socket編程準(zhǔn)備 1.地址 2.端口 3.網(wǎng)絡(luò)字節(jié)序 4.半相關(guān)與全相...
    VD2012閱讀 2,299評(píng)論 0 5
  • 一续室、 概述UNIX Domain Socket是在socket架構(gòu)上發(fā)展起來的用于同一臺(tái)主機(jī)的進(jìn)程間通訊(IPC)...
    chandarlee閱讀 6,777評(píng)論 0 51
  • 大綱 一.Socket簡(jiǎn)介 二.BSD Socket編程準(zhǔn)備 1.地址 2.端口 3.網(wǎng)絡(luò)字節(jié)序 4.半相關(guān)與全相...
    y角閱讀 2,390評(píng)論 2 11
  • 說明 本文 翻譯自 realpython 網(wǎng)站上的文章教程 Socket Programming in Pytho...
    keelii閱讀 2,111評(píng)論 0 16