Socket API

理解 Socket 首先要熟悉 TCP/IP 協(xié)議簇,TCP/IP(Transmission Control Protocol/Internet Protocol,傳輸控制協(xié)議/網(wǎng)間協(xié)議)定義了主機(jī)如何接入Internet 及數(shù)據(jù)如何傳輸?shù)臉?biāo)準(zhǔn)。

TCP/IP網(wǎng)絡(luò)協(xié)議

TCP/IP 是 TCP 和 IP 協(xié)議的合稱,但實(shí)際上 TCP/IP 協(xié)議是指 Internet 整個(gè) TCP/IP 協(xié)議簇,不同于 ISO 七層模型的分層,TCP/IP 協(xié)議參考模型把所有 TCP/IP 系列協(xié)議歸納抽象為4層:

  • 應(yīng)用層 協(xié)議:TFTP、HTTP、SNMP、FTP、SMTP、DNS、Telnet...
  • 傳輸層 協(xié)議:TCP、UDP
  • 網(wǎng)路層 協(xié)議:IP、ICMP、OSPF、EIGRP、IGMP
  • 數(shù)據(jù)鏈路層 協(xié)議:SLIP、CSLIP、PPP、MTU

TCP/IP是一種工業(yè)標(biāo)準(zhǔn)的協(xié)議集,為廣域網(wǎng) WAN 而設(shè)計(jì)。每一個(gè)抽象層建立在低一層所提供的服務(wù)上,并為高一層提供服務(wù)。

在 TCP/IP 協(xié)議中兩個(gè) Internet 主機(jī)通過路由器和對(duì)應(yīng)的層連接,各主機(jī)上得應(yīng)用通過數(shù)據(jù)通道相互執(zhí)行讀取操作。

TCP與IP

本地進(jìn)程間通信

”進(jìn)程通信“的概念最初來源于單機(jī)系統(tǒng),由于每個(gè)進(jìn)程都在自己地址范圍內(nèi)運(yùn)行,為保證兩個(gè)相互通信的進(jìn)程之間互不干擾又協(xié)調(diào)一致的工作,操作系統(tǒng)為進(jìn)程通信提供了相應(yīng)的設(shè)施。

本地進(jìn)程間通信IPC方式

  • 消息傳遞:管道、FIFO、消息隊(duì)列
  • 同步:互斥量、條件變量、讀寫鎖、文件和寫記錄鎖、信號(hào)量
  • 共享內(nèi)存:具名、匿名
  • 遠(yuǎn)程過程調(diào)用:RPC

網(wǎng)絡(luò)進(jìn)程間通信

本地進(jìn)程可通過進(jìn)程號(hào)(Process ID, PID)唯一標(biāo)識(shí),網(wǎng)絡(luò)中進(jìn)程間如何通信呢?首先要解決的問題是如何唯一標(biāo)識(shí)一個(gè)進(jìn)程,其實(shí)網(wǎng)絡(luò)中TCP/IP已經(jīng)解決了這個(gè)問題。

  • 網(wǎng)絡(luò)層 IP地址可以唯一標(biāo)識(shí)網(wǎng)絡(luò)中的主機(jī)
  • 傳輸層 “協(xié)議+端口”可以唯一標(biāo)識(shí)主機(jī)中的應(yīng)用程序(進(jìn)程)

“IP地址+協(xié)議+端口”可以標(biāo)識(shí)網(wǎng)絡(luò)的進(jìn)程,網(wǎng)絡(luò)中進(jìn)程通信即可實(shí)現(xiàn)。

什么是Socket

Socket英文愿意是“插孔”或“插座”,作為BSD UNIX的進(jìn)程通信機(jī)制后,取后一種意思,通常也被稱為套接字。使用TCP/IP協(xié)議的應(yīng)用程序通常采用的應(yīng)用編程接是UNIX BSD的套接字Socket,來實(shí)現(xiàn)網(wǎng)絡(luò)進(jìn)程之間的通信。

Socket用于描述IP地址和端口,是一個(gè)通信鏈的句柄,用來實(shí)現(xiàn)不同虛擬機(jī)或物理機(jī)之間的通信。應(yīng)用程序通過Socket向網(wǎng)絡(luò)發(fā)出請求或應(yīng)答請求。網(wǎng)絡(luò)中兩個(gè)進(jìn)程通過一個(gè)雙向的通信連接實(shí)現(xiàn)數(shù)據(jù)的交換,建立網(wǎng)絡(luò)通信連接至少需要一對(duì)Socket,連接的一端稱為一個(gè)Socket。

具有唯一標(biāo)識(shí)的網(wǎng)絡(luò)進(jìn)程可利用 Socket 進(jìn)行通信,而 Socket 是在應(yīng)用層和傳輸層之間的一個(gè)抽象層,Socket把TCP/IP層復(fù)雜的操作抽象為簡單的接口供應(yīng)用層調(diào)用,以實(shí)現(xiàn)進(jìn)程在網(wǎng)絡(luò)中的通信。TCP/IP協(xié)議存在于操作系統(tǒng)中,網(wǎng)絡(luò)服務(wù)是通過操作系統(tǒng)提供的,因此在操作系統(tǒng)中增加支持TCP/IP的系統(tǒng)調(diào)用Socket。

Socket 作為應(yīng)用層與 TCP/IP 協(xié)議簇通信的中間軟件抽象層,是一組接口。在設(shè)計(jì)模式中 Socket 其實(shí)就是一個(gè)門面模式,它將復(fù)雜的 TCP/IP 協(xié)議簇隱藏在 Socket 接口后面。對(duì)用戶而言一組簡單地接口就是全部,讓 Socket 去組織數(shù)據(jù)已符合指定的協(xié)議。

Socket抽象層

Socket通信流程

Socket可理解為一種特殊的文件,在服務(wù)器和客戶端各自維護(hù)一個(gè)文件,并使用SocketAPI函數(shù)對(duì)其進(jìn)行文件操作。在建立連接打開后,可以向各自文件寫入內(nèi)容供對(duì)方讀取或讀取對(duì)方內(nèi)容,通信結(jié)束時(shí)關(guān)閉文件。在UNIX哲學(xué)中“一切皆文件”,文件的操作模式基本為“打開-讀寫-關(guān)閉”三大步驟,Socket其實(shí)就是這個(gè)模式的一個(gè)實(shí)現(xiàn)。

Socket通信流程

服務(wù)器

  1. 服務(wù)器根據(jù)IP地址類型(IPv4/IPv6)、Socket 類型和協(xié)議創(chuàng)建套接字
  2. 服務(wù)端為 Socket 綁定 IP 地址和端口號(hào)
  3. 服務(wù)端 Socket 監(jiān)聽端口請求,隨時(shí)準(zhǔn)備接收客戶端發(fā)來的連接,此時(shí) socket 并未被打開。

客戶端

  1. 客戶端打開 Socket,根據(jù)服務(wù)器 IP 地址和端口試圖連接服務(wù)端的Socket。
  2. 服務(wù)器Socket接收到客戶端Socket請求,被動(dòng)打開開始接收客戶端請求,直到客戶端返回連接信息,此時(shí) Socket 進(jìn)入阻塞狀態(tài)。

交互過程

  1. 客戶端連接成功向服務(wù)端發(fā)送連接狀態(tài)信息
  2. 服務(wù)端 Accept 返回連接成功
  3. 客戶端向 Socket 寫入數(shù)據(jù)
  4. 服務(wù)端讀取數(shù)據(jù)
  5. 客戶端關(guān)閉

伯克利SocketAPI

歷史

  • Berkeley sockets 也稱為BSD Socket
  • 1983 BSD Socket4.
  • 1989 UNIX均采用
  • 2008 成為POSIX標(biāo)準(zhǔn)

頭文件

  • sys/socket.h 函數(shù)和數(shù)據(jù)結(jié)構(gòu)定義
  • netinet/in.h IPv4和IPv6xiangguan協(xié)議
  • sys/un.h UNIX機(jī)器間通信
  • arpa/inet.h 處理數(shù)字從操作系統(tǒng)字節(jié)序到網(wǎng)絡(luò)字節(jié)序
  • netdb.h 映射服務(wù)到IP地址

SocketAPI函數(shù)

socket() 創(chuàng)建套接字,根據(jù)指定地址、數(shù)據(jù)類型、協(xié)議分配一個(gè)套接字的描述字及所用資源。

int socket(int domain, int type, int protocol)

參數(shù):

  • domain
    協(xié)議簇/域,通常為AF_INET(IPv4)、AF_INET6(IPv6)
  • type
    套接字類型,主要是SOCK_STREAM(TCP)、SOCK_DGRAM(UDP)
  • protocol
    通常為0

Socket有3種類型

  • 流式 SOCK_STREAM
    流失套接字提供可靠的、面向連接的通信流,使用TCP協(xié)議從而保證數(shù)據(jù)傳輸?shù)恼_性和順序性。
  • 數(shù)據(jù)報(bào)SOCK_DGRAM
    數(shù)據(jù)包套接字定義了一種無連接的服務(wù),數(shù)據(jù)通過相互獨(dú)立的報(bào)文進(jìn)行傳輸,是無序的,不保證是可靠的無差錯(cuò)的,使用數(shù)據(jù)報(bào)協(xié)議UDP。
  • 原始SOCK_RAW
    原始套接字允許對(duì)底層協(xié)議如IP或ICMP進(jìn)行直接訪問,功能強(qiáng)大但使用不便,主要用于協(xié)議開發(fā)。

返回值:
成功時(shí)返回非負(fù)整數(shù)

  • bind() 綁定socket到IP地址和端口
  • listen() 服務(wù)器監(jiān)聽客戶端的連接
  • connect() 客戶端連接到服務(wù)器
  • accept() 應(yīng)用程序接收完成3次握手的客戶端連接
  • send()
  • recv()
  • write()
  • read()
  • close() 關(guān)閉socket
  • gethostbyname()IPv4專用
  • gethostbyaddr() IPv4專用
  • select()
  • poll() 處理多個(gè)連接的讀寫和錯(cuò)誤狀態(tài)
  • getsocketopt() 獲得對(duì)應(yīng)socket的選項(xiàng)值
  • setsocketopt() 設(shè)置對(duì)應(yīng)socket的選項(xiàng)值
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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