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