Socket編程(2)-Socket抽象機(jī)制

1 Socket API簡介

1.1 最初設(shè)計(jì)

最初設(shè)計(jì)是基于BSD UNIX-Berkley,面向TCP/IP協(xié)議棧的接口。經(jīng)過后續(xù)的發(fā)展,已經(jīng)可以面向多個(gè)協(xié)議棧。Socket API也是事實(shí)上的工業(yè)標(biāo)準(zhǔn),絕大多數(shù)的操作系統(tǒng)都支持,主流的操作系統(tǒng)如Windows和Linux都是支持的。Windows和Linux操作系統(tǒng)下Socket API的功能是有重疊的,基本編程思路不變,只需改動極小量的代碼即可在相應(yīng)操作系統(tǒng)編譯、鏈接、運(yùn)行。

1.2 形象比喻

首先,Socket API是Internet網(wǎng)絡(luò)應(yīng)用最典型的API接口,使用的通信模型為客戶/服務(wù)器模型(C/S),這類模型描述了應(yīng)用進(jìn)程間通信的抽象機(jī)制。
我們可以將socket形象比喻成插頭與插座,現(xiàn)在你想要給自己的手機(jī)充電,需要什么東西才能通過插座給手機(jī)充電呢?那就是適配手機(jī)的充電線和充電插頭,在此我們把它們看成一個(gè)整體,叫做充電工具。現(xiàn)在你只需要將充電工具的USB插口一端與手機(jī)連接,另一端插頭插到插座上,手機(jī)就能夠進(jìn)行充電,我們無須了解插座后面的電路構(gòu)造,只要將插頭插入插座就能使用充電功能,這就是API的現(xiàn)實(shí)體現(xiàn)。

1.3 通信定位

在一臺主機(jī)上可能運(yùn)行多個(gè)進(jìn)程,比如現(xiàn)在打開的簡書Web應(yīng)用或者QQ,假設(shè)突然有個(gè)套接字要過來和你的進(jìn)程通信,那現(xiàn)在主機(jī)上那么多進(jìn)程,它應(yīng)該和哪個(gè)進(jìn)程通信?換句話說,它應(yīng)該如何找到指定的進(jìn)程進(jìn)行通信?再形象點(diǎn),插頭要插哪個(gè)插座上?我們要如何準(zhǔn)確定位服務(wù)器端的套接字呢?
其實(shí)很簡單,在某一特定網(wǎng)絡(luò)中,一臺主機(jī)對應(yīng)唯一的IP地址,服務(wù)器其實(shí)也是網(wǎng)絡(luò)上的一臺主機(jī),也對應(yīng)一個(gè)IP地址,這其實(shí)就能找到主機(jī)的地址。以五層模型為參考,主機(jī)間應(yīng)用層的交互實(shí)際上是通過底層傳輸層協(xié)議來進(jìn)行交互,操作系統(tǒng)需要提供端口來給進(jìn)程,即端口號。
對外(主機(jī)與主機(jī)間)來說,套接字通過IP地址+端口號來標(biāo)識通信端點(diǎn),這樣的標(biāo)識是唯一的。對內(nèi)(主機(jī)本身)來說,操作系統(tǒng)使用套接字描述符(socket descriptor)來管理套接字,大小一般是小整數(shù)。由此可見,套接字對內(nèi)對外管理是不一樣的。

  • 需要標(biāo)識通信端點(diǎn)(對外):IP地址+Port端口號→套接字的端點(diǎn)地址
    (1)IP地址標(biāo)識互聯(lián)網(wǎng)中的機(jī)器地址。
    (2)Port端口號為16位整數(shù),標(biāo)識某一具體機(jī)器的進(jìn)程,綁定套接字。
  • 操作系統(tǒng)/進(jìn)程管理套接字(對內(nèi)):使用套接字描述符(socket descriptor)。

2 socket抽象

2.1 socket創(chuàng)建

  1. 在Unix、Linux操作系統(tǒng)中,將socket看作文件。
  2. 當(dāng)應(yīng)用進(jìn)程創(chuàng)建套接字時(shí),操作系統(tǒng)分配一個(gè)數(shù)據(jù)結(jié)構(gòu)存儲該套接字相關(guān)信息。
  3. 返回套接字描述符。

2.2 socket管理

每個(gè)進(jìn)程管理一個(gè)socket描述符表,表中的入口都有一個(gè)指針,指向所存儲的數(shù)據(jù)結(jié)構(gòu)。

socket描述符表 socket數(shù)據(jù)結(jié)構(gòu)
[0] struct sockaddr_in *
[1] 其他數(shù)據(jù)結(jié)構(gòu)
[2] 其他數(shù)據(jù)結(jié)構(gòu)
... 其他數(shù)據(jù)結(jié)構(gòu)

作為套接字最重要的信息就是套接字的地址信息,使用前需要指定本地的端點(diǎn)地址和遠(yuǎn)程的端點(diǎn)地址。使用TCP/IP協(xié)議簇的網(wǎng)絡(luò)應(yīng)用程序聲明端點(diǎn)地址變量時(shí),通過結(jié)構(gòu)sockaddr_in來描述地址信息,使用前需要include <netinet/in.h>。

struct sockaddr_in{
    u_char sin_len;       // 地址長度
    u_char sin_family;    // 地址族(TCP/IP:AF_INET) 面向各種不同的協(xié)議棧,主要是TCP
    u_short sin_port;    // 端口號
    struct in_addr sin_addr;    // IP地址
    char sin_zero[8];    // 未用(置0)  填充0以保持與sockaddr結(jié)構(gòu)的長度相同
}

不同地址族(協(xié)議棧)的端點(diǎn)地址是不一樣的,TCP/IP協(xié)議簇的端點(diǎn)地址為IP+Port,通常指定其sin_family數(shù)據(jù)成員為AF_INET符號常量,表示本身為TCP/IP協(xié)議簇。

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

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

  • 第一章 TCP/IP簡介 基本的C/S服務(wù)模型 網(wǎng)絡(luò)編程是指編寫的網(wǎng)絡(luò)通信程序可以與網(wǎng)絡(luò)上的其他程序進(jìn)行通信。 T...
    Waldo_cuit閱讀 1,988評論 0 6
  • Linux系統(tǒng)的一大特點(diǎn)是它的網(wǎng)絡(luò)編程能力十分強(qiáng)大, 學(xué)習(xí)它, 讓我們真正體會網(wǎng)絡(luò)的魅力! 一. 客戶機(jī)/服務(wù)器模...
    劉元旺閱讀 6,632評論 0 5
  • 網(wǎng)絡(luò)編程 一.楔子 你現(xiàn)在已經(jīng)學(xué)會了寫python代碼,假如你寫了兩個(gè)python文件a.py和b.py,分別去運(yùn)...
    go以恒閱讀 2,247評論 0 6
  • 什么是Socket Socket是進(jìn)程通訊的一種方式,即調(diào)用這個(gè)網(wǎng)絡(luò)庫的一些API函數(shù)實(shí)現(xiàn)分布在不同主機(jī)的相關(guān)進(jìn)程...
    onlyHalfSoul閱讀 706評論 0 1
  • 最后一天下午的學(xué)習(xí)是寇乃馨老師的課,瞬間就喜歡上她的風(fēng)格了,犀利不乏幽默,直言不乏智慧,高調(diào)不乏落地,美麗不乏內(nèi)涵...
    閃耀的珍珠閱讀 281評論 0 0

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