socket的引入是為了解決不同計(jì)算機(jī)間進(jìn)程間通信的問(wèn)題。
端口是TCP/IP協(xié)議中的概念,描述的是TCP協(xié)議上的對(duì)應(yīng)的應(yīng)用,可以理解為基于TCP的系統(tǒng)服務(wù),或者說(shuō)系統(tǒng)進(jìn)程!如下圖,F(xiàn)TP就需要占用特定的TCP端口。
而 socket 呢,是網(wǎng)絡(luò)編程中的概念,對(duì)TCP/IP協(xié)議進(jìn)行了抽象和實(shí)現(xiàn),并為應(yīng)用層提供接口。這里的應(yīng)用A,可以是FTP應(yīng)用,它屬于用戶進(jìn)程,通過(guò)socket與內(nèi)核中的網(wǎng)絡(luò)協(xié)議棧進(jìn)行交互。
socket 是核心,是樞紐,是進(jìn)程與網(wǎng)絡(luò)建立關(guān)系的必經(jīng)之路!
1.內(nèi)核是如何將數(shù)據(jù)包轉(zhuǎn)發(fā)至 socket 的呢?
網(wǎng)絡(luò)數(shù)據(jù)首先到達(dá)網(wǎng)卡,然后進(jìn)入內(nèi)核,由網(wǎng)絡(luò)協(xié)議棧去處理,那么內(nèi)核是如何進(jìn)行數(shù)據(jù)分發(fā)的呢?它怎么知道該如何把數(shù)據(jù)交給特定的用戶進(jìn)程呢?
這時(shí),就需要 socket 發(fā)揮作用了!
socket 中存儲(chǔ)了特定的四元組:源ip+port,目的ip+port;
1 > bind 到特定 ip 和 port 的socket 對(duì)應(yīng) [src ip, src port) <= > (*, *)] ;
2 > connect 到特定目的ip+port 的 socket 對(duì)應(yīng) [src ip, src port) <= > (dst ip, dst port)];
3 > accept 返回了的 socket 對(duì)應(yīng) [src ip, src port) <= > (dst ip, dst port)];
那么內(nèi)核根據(jù)數(shù)據(jù)包的四元組信息,就可以鎖定特定的socket了。并可,系統(tǒng)中所有 socket 中的四元組信息,必定唯一,不可能重復(fù)!
2 進(jìn)程與socket的關(guān)系是怎樣的呢?
每個(gè)進(jìn)程,在內(nèi)核中都有一個(gè)表,保存了該進(jìn)程申請(qǐng)并占用的所有 socket 描述符,在進(jìn)程看來(lái),socket 其實(shí)跟文件也沒(méi)有什么不同,只不過(guò)通過(guò)描述符獲得的對(duì)象不同而已,接口對(duì)應(yīng)的系統(tǒng)調(diào)用也不同。
那么進(jìn)程跟socket是一一對(duì)應(yīng)的嗎?
其實(shí)不然,socket是一種資源,就像文件一樣,一個(gè)進(jìn)程打開(kāi)了,另一個(gè)進(jìn)程也可以用,只不過(guò)socket比較特殊而已。
理論上,能夠通過(guò) sendmsg 將 socket 描述符傳遞給其他進(jìn)程,這樣其他進(jìn)程就可以調(diào)用該描述符的接口了。這種場(chǎng)景確實(shí)不怎么會(huì)用到,也沒(méi)有進(jìn)行實(shí)際驗(yàn)證。
當(dāng)然,父子進(jìn)程間,還有線程間,進(jìn)行 socket 的共享,是比較常見(jiàn)的。
3 進(jìn)程與端口
進(jìn)程與端口,其實(shí)并沒(méi)有什么直接或必然的關(guān)系,關(guān)鍵還是socket!
wireshark 抓包查看tcp協(xié)議數(shù)據(jù)包詳情:
總結(jié)
socket 的本質(zhì)是一種資源,它包含了端到端的四元組信息,用來(lái)標(biāo)識(shí)數(shù)據(jù)包的歸屬。因此,盡管 tcp 協(xié)議的端口號(hào)只有 65535 個(gè),但是進(jìn)程可擁有的 socket 數(shù)據(jù)卻不限于此(受限于進(jìn)程最大文件描述符數(shù)據(jù));
PS:
一、端口簡(jiǎn)介
隨著計(jì)算機(jī)網(wǎng)絡(luò)技術(shù)的發(fā)展,原來(lái)物理上的接口(如鍵盤、鼠標(biāo)、網(wǎng)卡、顯示卡等輸入/輸出接口)已不能滿足網(wǎng)絡(luò)通信的要求,TCP/IP協(xié)議作為網(wǎng)絡(luò)通信的標(biāo)準(zhǔn)協(xié)議就解決了這個(gè)通信難題。TCP/IP協(xié)議集成到操作系統(tǒng)的內(nèi)核中,這就相當(dāng)于在操作系統(tǒng)中引入了一種新的輸入/輸出接口技術(shù),因?yàn)樵赥CP/IP協(xié)議中引入了一種稱之為Socket(套接字)應(yīng)用程序接口。有了這樣一種接口技術(shù),一臺(tái)計(jì)算機(jī)就可以通過(guò)軟件的方式與任何一臺(tái)具有Socket接口的計(jì)算機(jī)進(jìn)行通信。端口在計(jì)算機(jī)編程上也就是Socket接口。
有了這些端口后,這些端口又是如何工作呢?例如一臺(tái)服務(wù)器為什么可以同時(shí)是Web服務(wù)器,也可以是FTP服務(wù)器,還可以是郵件服務(wù)器等等呢?其中一個(gè)很重要的原因是各種服務(wù)采用不同的端口分別提供不同的服務(wù),比如:通常TCP/IP協(xié)議規(guī)定Web采用80號(hào)端口,F(xiàn)TP采用21號(hào)端口等,而郵件服務(wù)器是采用25號(hào)端口。這樣,通過(guò)不同端口,計(jì)算機(jī)就可以與外界進(jìn)行互不干擾的通信。
據(jù)專家們分析,服務(wù)器端口數(shù)最大可以有65535個(gè),但是實(shí)際上常用的端口才幾十個(gè),由此可以看出未定義的端口相當(dāng)多。這是那么多黑客程序都可以采用某種方法,定義出一個(gè)特殊的端口來(lái)達(dá)到入侵的目的的原因所在。為了定義出這個(gè)端口,就要依靠某種程序在計(jì)算機(jī)啟動(dòng)之前自動(dòng)加載到內(nèi)存,強(qiáng)行控制計(jì)算機(jī)打開(kāi)那個(gè)特殊的端口。這個(gè)程序就是后門程序,這些后門程序就是常說(shuō)的木馬程序。簡(jiǎn)單的說(shuō),這些木馬程序在入侵前是先通過(guò)某種手段在一臺(tái)個(gè)人計(jì)算機(jī)中植入一個(gè)程序,打開(kāi)某個(gè)(些)特定的端口,俗稱后門(BackDoor),使這臺(tái)計(jì)算機(jī)變成一臺(tái)開(kāi)放性極高(用戶擁有極高權(quán)限)的FTP服務(wù)器,然后從后門就可以達(dá)到侵入的目的。
二、端口的分類
端口的分類根據(jù)其參考對(duì)象不同有不同劃分方法,如果從端口的性質(zhì)來(lái)分,通??梢苑譃橐韵氯悾?/p>
(1)公認(rèn)端口(Well KnownPorts):這類端口也常稱之為常用端口。這類端口的端口號(hào)從0到1024,它們緊密綁定于一些特定的服務(wù)。通常這些端口的通信明確表明了某種服務(wù)的協(xié)議,這種端口是不可再重新定義它的作用對(duì)象。例如:80端口實(shí)際上總是HTTP通信所使用的,而23號(hào)端口則是Telnet服務(wù)專用的。這些端口通常不會(huì)像木馬這樣的黑客程序利用。
(2) 注冊(cè)端口(Registered Ports):端口號(hào)從1025到49151。它們松散地綁定于一些服務(wù)。也是說(shuō)有許多服務(wù)綁定于這些端口,這些端口同樣用于許多其他目的。這些端口多數(shù)沒(méi)有明確的定義服務(wù)對(duì)象,不同程序可根據(jù)實(shí)際需要自己定義,如后面要介紹的遠(yuǎn)程控制軟件和木馬程序中都會(huì)有這些端口的定義的。記住這些常見(jiàn)的程序端口在木馬程序的防護(hù)和查殺上是非常有必要的。常見(jiàn)木馬所使用的端口在后面將有詳細(xì)的列表。
(3) 動(dòng)態(tài)和/或私有端口(Dynamic and/or Private Ports):端口號(hào)從49152到65535。理論上,不應(yīng)把常用服務(wù)分配在這些端口上。實(shí)際上,有些較為特殊的程序,特別是一些木馬程序就非常喜歡用這些端口,因?yàn)檫@些端口常常不被引起注意,容易隱蔽。
如果根據(jù)所提供的服務(wù)方式的不同,端口又可分為TCP協(xié)議端口和UDP協(xié)議端口兩種。因?yàn)橛?jì)算機(jī)之間相互通信一般采用這兩種通信協(xié)議。前面所介紹的連接方式是一種直接與接收方進(jìn)行的連接,發(fā)送信息以后,可以確認(rèn)信息是否到達(dá),這種方式大多采用TCP協(xié)議;另一種是不是直接與接收方進(jìn)行連接,只管把信息放在網(wǎng)上發(fā)出去,而不管信息是否到達(dá),也就是前面所介紹的無(wú)連接方式。這種方式大多采用UDP協(xié)議,IP協(xié)議也是一種無(wú)連接方式。對(duì)應(yīng)使用以上這兩種通信協(xié)議的服務(wù)所提供的端口,也就分為TCP協(xié)議端口和UDP協(xié)議端口。
使用TCP協(xié)議的常見(jiàn)端口主要有以下幾種:
(1) FTP:定義了文件傳輸協(xié)議,使用21端口。常說(shuō)某某計(jì)算機(jī)開(kāi)了FTP服務(wù)便是啟動(dòng)了文件傳輸服務(wù)。下載文件,上傳主頁(yè),都要用到FTP服務(wù)。
(2)Telnet:它是一種用于遠(yuǎn)程登陸的端口,用戶可以以自己的身份遠(yuǎn)程連接到計(jì)算機(jī)上,通過(guò)這種端口可以提供一種基于DOS模式下的通信服務(wù)。如以前的BBS是純字符界面的,支持BBS的服務(wù)器將23端口打開(kāi),對(duì)外提供服務(wù)。
(3)SMTP:定義了簡(jiǎn)單郵件傳送協(xié)議,現(xiàn)在很多郵件服務(wù)器都用的是這個(gè)協(xié)議,用于發(fā)送郵件。如常見(jiàn)的免費(fèi)郵件服務(wù)中用的就是這個(gè)郵件服務(wù)端口,所以在電子郵件設(shè)置中??吹接羞@么SMTP端口設(shè)置這個(gè)欄,服務(wù)器開(kāi)放的是25號(hào)端口。
socket介紹
socket為內(nèi)核對(duì)象,由操作系統(tǒng)內(nèi)核來(lái)維護(hù)其緩沖區(qū),引用計(jì)數(shù),并且可以在多個(gè)進(jìn)程中使用。至于稱它為“句柄”“文件描述符”都是一樣的,它只不過(guò)是內(nèi)核開(kāi)放給用戶進(jìn)程使用的整數(shù)而已。
socket() 創(chuàng)建了一個(gè)socket內(nèi)核對(duì)象。accept或者connect后,才可以對(duì)socket句柄讀寫。因?yàn)橹挥性?connect或者bind,listen,accept后才會(huì)設(shè)置好socket內(nèi)核對(duì)象里邊的ip和端口 。
在使用socket編程時(shí),我們都知道在網(wǎng)絡(luò)通信以前首先要建立連接,而連接的建立是通過(guò)對(duì)socket的一些操作來(lái)完成的。那么,建立連接的過(guò)程大致可以分為以下幾步:
1) 建立socket套接字。
2) 給套接字賦予地址,這個(gè)地址不是通常的網(wǎng)絡(luò)地址的概念。
3) 建立socket連接。
以下詳細(xì)解釋
1. 建立socket套接字。
使用socket建立套接字的時(shí)候,我們實(shí)際上是建立了一個(gè)數(shù)據(jù)結(jié)構(gòu)。這個(gè)數(shù)據(jù)結(jié)構(gòu)最主要的信息是指定了連接的種類和使用的協(xié)議,此外還有一些關(guān)于連接隊(duì)列操作的結(jié)構(gòu)字段(這里就先不涉及他們了)。
當(dāng)我們使用socket函數(shù)以后,如果成功的話會(huì)返回一個(gè)int型的描述符,它指向前面那個(gè)被維護(hù)在內(nèi)核里的socket數(shù)據(jù)結(jié)構(gòu)。我們的任何操作都是通過(guò)這個(gè)描述符而作用到那個(gè)數(shù)據(jù)結(jié)構(gòu)上的。這就像是我們?cè)诮⒁粋€(gè)文件后得到一個(gè)文件描述符一樣,對(duì)文件的操作都是通過(guò)文件描述符來(lái)進(jìn)行的,而不是直接作用到inode數(shù)據(jù)結(jié)構(gòu)上。我之所以用文件描述符舉例,是因?yàn)閟ocket數(shù)據(jù)結(jié)構(gòu)也是和inode數(shù)據(jù)結(jié)構(gòu)密切相關(guān),它不是獨(dú)立存在于內(nèi)核中的,而是位于一個(gè)VFS inode結(jié)構(gòu)中。所以,有一些比較抽象的特性,我們可以用文件操作來(lái)不恰當(dāng)?shù)倪M(jìn)行類比以加深理解。
如前所述,當(dāng)建立了這個(gè)套接字以后,我們可以獲得一個(gè)象文件描述符那樣的套接字描述符。就象我們對(duì)文件進(jìn)行操作那樣,我們可以通過(guò)向套接字里面寫數(shù)據(jù)將數(shù)據(jù)傳送到我們指定的地方,這個(gè)地方可以是遠(yuǎn)端的主機(jī),也可以是本地的主機(jī)。如果你有興趣的話,還可以用socket機(jī)制來(lái)實(shí)現(xiàn)IPC,不過(guò)效率比較低,試試也就行了(沒(méi)有試過(guò))。
2. 給套接字賦予地址。
依照建立套接字的目的不同,賦予套接字地址的方式有兩種:服務(wù)器端使用bind,客戶端使用connetc。
Bind:
我們都知道,只要使用IP, prot就可以區(qū)分一個(gè)tcp/ip連接(當(dāng)然這個(gè)連接指的是一個(gè)連接通道,如果要區(qū)分特定的主機(jī)間的連接,還需要第三個(gè)屬性 hostname)。
我們可以使用bind函數(shù)來(lái)為一個(gè)使用在服務(wù)器端例程中的套接字賦予通信的地址和端口。
在這里我們稱通信的IP地址和端口合起來(lái)構(gòu)成了一個(gè)socket地址,而指定一個(gè)socket使用特定的IP和port組合來(lái)進(jìn)行通行的過(guò)程就是賦予這個(gè)socket一個(gè)地址。要賦予socket地址,就得使用一個(gè)數(shù)據(jù)結(jié)構(gòu)來(lái)指明特定的socket地址,這個(gè)數(shù)據(jù)結(jié)構(gòu)就是struct sockaddr。對(duì)它的使用我就不說(shuō)了,因?yàn)檫@篇文檔的目的是澄清概念而不是說(shuō)明使用方法。Bind函數(shù)的作用就是將這個(gè)特定的標(biāo)注有socket地址信息的數(shù)據(jù)結(jié)構(gòu)和socket套接字聯(lián)系起來(lái),即賦予這個(gè)套接字一個(gè)地址。但是在具體實(shí)現(xiàn)上,他們兩個(gè)是怎么聯(lián)系在一起的,我還不知道。
一個(gè)特定的socket的地址的生命期是bind成功以后到連接斷開(kāi)前。你可以建立一個(gè)socket數(shù)據(jù)結(jié)構(gòu)和socket地址的數(shù)據(jù)結(jié)構(gòu),但是在沒(méi)有bind以前他們兩個(gè)是沒(méi)有關(guān)系的,在bind以后他們兩個(gè)才有了關(guān)系。這種關(guān)系一直維持到連接的結(jié)束,當(dāng)一個(gè)連接結(jié)束時(shí),socket數(shù)據(jù)結(jié)構(gòu)和socket地址的數(shù)據(jù)結(jié)構(gòu)還都存在,但是他們兩個(gè)已經(jīng)沒(méi)有關(guān)系了。如果你要是用這個(gè)套接字在socket地址上重新進(jìn)行連接時(shí),需重新bind他們兩個(gè)。再注明一次,我說(shuō)的這個(gè)連接是一個(gè)連接通道,而不是特定的主機(jī)之間的連接。
Bind指定的IP通常是本地IP(一般不特別指定,而使用INADDR_ANY來(lái)聲明),而最主要的作用是指定端口。在服務(wù)器端的socket進(jìn)行了bind以后就是用listen來(lái)在這個(gè)socket地址上準(zhǔn)備進(jìn)行連接。
connect:
對(duì)于客戶端來(lái)說(shuō),是不會(huì)使用bind的(并不是不能用,但沒(méi)什么意義),他們會(huì)通過(guò)connet函數(shù)來(lái)建立socket和socket地址之間的關(guān)系。其中的socket地址是它想要連接的服務(wù)器端的socket地址。在connect建立socket和socket地址兩者關(guān)系的同時(shí),它也在嘗試著建立遠(yuǎn)端的連接。
3. 建立socket連接。
對(duì)于準(zhǔn)備建立一個(gè)連接,服務(wù)器端要兩個(gè)步驟:bind, listen;客戶端一個(gè)步驟:connct。如果服務(wù)器端accept一個(gè)connect,而客戶端得到了這個(gè)accept的確認(rèn),那么一個(gè)連接就建立了。
-
Socket
+關(guān)注
關(guān)注
0文章
212瀏覽量
34664 -
網(wǎng)絡(luò)協(xié)議
+關(guān)注
關(guān)注
3文章
267瀏覽量
21534 -
TCP
+關(guān)注
關(guān)注
8文章
1353瀏覽量
79055 -
端口
+關(guān)注
關(guān)注
4文章
963瀏覽量
32051
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論